首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >guid到base64的base64

guid到base64的base64
EN

Stack Overflow用户
提问于 2011-03-03 03:08:18
回答 3查看 13K关注 0票数 4

我目前正在研究MongoDb作为一种可能的数据库选项,但我在处理Guid序列化时遇到了麻烦。起初我认为这可能是C#驱动程序序列化中的一个错误,但现在我认为这更可能是我的一个天真的假设。

为了帮助我将Bson base64表示来回转换为Guids,我编写了几个小powershell函数来提供帮助:

代码语言:javascript
复制
function base64toguid  
{  
    param($str);  
    $b = [System.Convert]::FromBase64String($str);
    $hex = "";
    foreach ($x in $b) {
        $hex += $x.ToString("x2");
    }
    $g = new-object -TypeName System.Guid -ArgumentList $hex;
    return $g;
}


function guidtobase64
{
    param($str);
    $g = new-object -TypeName System.Guid -ArgumentList $str;
    $b64 = [System.Convert]::ToBase64String($g.ToByteArray());
    return $b64;
}

下面是我遇到的问题的一个例子:

代码语言:javascript
复制
:) guidtobase64("53E32701-9863-DE11-BD66-0015178A5E3C");
ASfjU2OYEd69ZgAVF4pePA==
:) base64toguid("ASfjU2OYEd69ZgAVF4pePA==");

Guid
----
0127e353-6398-11de-bd66-0015178a5e3c

在mongo shell中:

代码语言:javascript
复制
:) mongo
MongoDB shell version: 1.6.5
connecting to: test
> b = new BinData(3, "ASfjU2OYEd69ZgAVF4pePA==");
BinData(3,"ASfjU2OYEd69ZgAVF4pePA==")
> b.hex();
127e353639811debd66015178a5e3c
>

如您所见,我得到的Guid与我输入的内容不匹配。我的函数和hex()返回相同的东西。如果将原始结果与结果进行比较:

53E32701-9863-DE11-BD66-0015178A5E3C

0127e353-6398-11de-bd66-0015178a5e3c

您可以看到,前3组十六进制对是颠倒的,但最后两组不是。这让我觉得Guid.ToString()有一些我不理解的地方。

有人能教教我吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-03 03:13:17

GUID中的字节顺序与它们在小端系统上的ToString()表示中的顺序不同。

您应该使用guid.ToByteArray()而不是ToString()。

而且,您应该使用new Guid(byte[] b)而不是$str来构造它。

要用纯C#来表达这一点:

代码语言:javascript
复制
public string GuidToBase64(Guid guid)
{
    return System.Convert.ToBase64String(guid.ToByteArray());  // Very similar to what you have.
}

public Guid Base64Toguid(string base64)
{
    var bytes = System.Convert.FromBase64String(base64);
    return new Guid(bytes);  // Not that I'm not building up a string to represent the GUID.
}

请查看维基百科上的"Basic Structure" section of the GUID article以了解更多细节。

你会发现大部分数据都是以“本地”字节顺序存储的……这就是困惑的来源。

引述如下:

Data4存储字节的顺序与GUID文本编码中显示的顺序相同(请参见下文),但在小端系统(例如英特尔CPU)上,其他三个字段的顺序是相反的。

编辑:

Powershell版本:

代码语言:javascript
复制
function base64toguid  
{  
    param($str);  
    $b = [System.Convert]::FromBase64String($str);
    $g = new-object -TypeName System.Guid -ArgumentList (,$b);
    return $g;
}

作为额外的警告,您可以选择将字符串末尾的"==“去掉,因为它只是填充(如果您试图节省空间,这可能会有所帮助)。

票数 13
EN

Stack Overflow用户

发布于 2011-03-03 03:26:19

您需要调用接受字节数组的Guid构造函数。在Powershell中有特殊的语法需要这样做-如果你只是传递$b,它会告诉你找不到接受16个参数的构造函数,所以你必须将字节数组包装在另一个数组中:

代码语言:javascript
复制
$g = new-object -TypeName System.Guid -ArgumentList (,$b)
票数 2
EN

Stack Overflow用户

发布于 2011-03-03 12:21:35

查看mongo网站上的c-sharp driver documentation,发现有一个为System.Guid提供的隐式转换。

所以在c#中(对不起,我的powershell有点生疏了),你可以这样写:

代码语言:javascript
复制
Guid g = Guid.NewGuid(); //or however your Guid is initialized
BsonValue b = g;

我想反之亦然:

代码语言:javascript
复制
BsonValue b = // obtained this from somewhere
Guid g = b;

如果您没有特别需要将Guid序列化为base64,那么直接将其转换为二进制文件的工作将会少得多(请注意,例如,将不会出现字节顺序问题)。此外,数据将以二进制形式存储在服务器上,因此它将比使用base64更节省空间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5172134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档