base64 to guid to base64

Eri*_*ard 4 powershell guid mongodb

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

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

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;
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题的一个例子:

:) guidtobase64("53E32701-9863-DE11-BD66-0015178A5E3C");
ASfjU2OYEd69ZgAVF4pePA==
:) base64toguid("ASfjU2OYEd69ZgAVF4pePA==");

Guid
----
0127e353-6398-11de-bd66-0015178a5e3c
Run Code Online (Sandbox Code Playgroud)

从mongo shell:

:) mongo
MongoDB shell version: 1.6.5
connecting to: test
> b = new BinData(3, "ASfjU2OYEd69ZgAVF4pePA==");
BinData(3,"ASfjU2OYEd69ZgAVF4pePA==")
> b.hex();
127e353639811debd66015178a5e3c
>
Run Code Online (Sandbox Code Playgroud)

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

53E32701-9863-DE11-BD66-0015178A5E3C
0127e353-6398-11de-bd66-0015178a5e3c

您可以看到前三组十六进制对是相反的,但最后两组不是.这让我觉得Guid.ToString()有一些我不明白的地方.

有人可以教育我吗?

Joh*_*zen 13

GUID中的字节顺序与它们ToString()在little-endian系统上的表示顺序不同.

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

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

用纯C#来表达这个:

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.
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请查看Wikipedia上GUID文章"基本结构"部分.

您将看到大多数数据都存储在"Native"字节序中......这就是混乱的来源.

报价:

Data4以与GUID文本编码(见下文)中显示的顺序相同的顺序存储字节,但其他三个字段在little-endian系统(例如Intel CPU)上相反.


编辑:

Powershell版本:

function base64toguid  
{  
    param($str);  
    $b = [System.Convert]::FromBase64String($str);
    $g = new-object -TypeName System.Guid -ArgumentList (,$b);
    return $g;
}
Run Code Online (Sandbox Code Playgroud)

作为一个额外的警告,您可以选择修剪字符串末尾的"==",因为它只是填充(如果您尝试节省空间,这可能会有所帮助).