base64 to guid to base64

拈花ヽ惹草 提交于 2019-12-04 09:36:29
John Gietzen

The order of bytes in a GUID are not the same as the order in their ToString() representation on little-endian systems.

You should use guid.ToByteArray() rather than using ToString().

And, you should use new Guid(byte[] b) to construct it, rather than $str.

To express this in pure 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.
}

Take a look at the "Basic Structure" section of the GUID article on Wikipedia for more details.

You will see that most of the data is stored in "Native" endianness... which is where the confusion is coming from.

To quote:

Data4 stores the bytes in the same order as displayed in the GUID text encoding (see below), but the other three fields are reversed on little-endian systems (for example Intel CPUs).


Edit:

Powershell version:

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

As an additional caveat, you can optionally trim the "==" off of the end of your string, since it is just padding (which may help if you are trying to save space).

You need to call the Guid constructor that takes a byte array. There's special syntax needed for that in Powershell - if you just pass $b it will tell you it can't find a constructor that takes 16 arguments, so you have to wrap the byte array in another array:

$g = new-object -TypeName System.Guid -ArgumentList (,$b)

Looking at the c-sharp driver documentation on the mongo website, it turns out that there is an implicit conversion provided for System.Guid.

So in c# (sorry, my powershell is a little rusty), you would just write:

Guid g = Guid.NewGuid(); //or however your Guid is initialized
BsonValue b = g;

I imagine that the reverse will probably also work:

BsonValue b = // obtained this from somewhere
Guid g = b;

If you have no specific need to serialize the Guid as base64, then converting directly to binary will be much less work (note that there will be no endian issues, for example). Also, the data will be stored in binary on the server, so it will be more space efficient than using base64.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!