在我的c ++程序中,我使用debian linux的uuid包生成一个uuid值,它返回一个大小为16的unsigned char数组,类型为uuid_t。然后我将其转换为字符串并将其打印到控制台。
然后我使用相同的字节数组并通过网络将其发送到Windows机器。 Windows机器使用.net的GUID类型,并使用相同的字节数组创建GUID对象。然后我使用GUID的ToString方法再次将其打印到控制台。令人惊讶的是,相同的字节数组在Linux和.Net下具有不同的字符串表示形式,即使它们几乎相似。
以下是一个例子:
字节数组:
101,208,176,173,236,192,64,86,191,214,132,2,213,232,143,247
Linux中: 65d0b0ad-ecc0-4056-bfd6-8402d5e88ff7
.NET: adb0d065-c0ec-5640-bfd6-8402d5e88ff7
您可能会注意到它们非常相似,最后的部分是相同的,第一部分使用相同的数字,只有数字的顺序不同。我按照上面解释的方式创建的每个UUID遵循相同的模式,这使我认为存在字节顺序差异。
如何在linux中创建UUID值并使用相同的字节数组具有相同的字符串表示。
答案 0 :(得分:2)
根据this和this消息,问题实际上是对GUID / UUID应该是大端还是小端的不同理解。看起来微软的实现将它们视为Big-Endian(至少在英特尔平台上),但uuid_unparse
似乎是Little-Endian。 Wiki表示GUID(微软的UUID)遵循RFC 4122, section 4.1.2,这似乎要求Big-Endian订购。
因此,这是实现之间的明显不一致。作为一种解决方法,我建议以字符串格式在系统之间交换数据,这似乎在两个系统中都是一致的。
答案 1 :(得分:0)
不幸的是,你不能拥有相同的字节数组和让Guid.ToString
产生一个与Linux字符串匹配的字符串。
您需要决定要优先考虑哪一个:
var dotNetGuid = new Guid(new byte[] { 101, 208, 176, 173, 236, 192, 64, 86,
191, 214, 132, 2, 213, 232, 143, 247 });
// option 1 - keep the existing guid's byte array intact
// and create a new ToUnixString method to display it as-required
Console.WriteLine(dotNetGuid.ToString()); // adb0d065-c0ec-5640-bfd6-8402d5e88ff7
Console.WriteLine(dotNetGuid.ToUnixString()); // 65d0b0ad-ecc0-4056-bfd6-8402d5e88ff7
// option 2 - create a new guid by re-arranging the existing guid's byte array
// and then use the standard ToString method
var unixGuid = dotNetGuid.ChangeByteOrder();
Console.WriteLine(dotNetGuid.ToString()); // adb0d065-c0ec-5640-bfd6-8402d5e88ff7
Console.WriteLine(unixGuid.ToString()); // 65d0b0ad-ecc0-4056-bfd6-8402d5e88ff7
// ...
public static class GuidExtensions
{
public static string ToUnixString(this Guid guid,
string format = "D", IFormatProvider provider = null)
{
return guid.ChangeByteOrder().ToString(format, provider);
}
public static Guid ChangeByteOrder(this Guid guid)
{
var s = guid.ToByteArray();
var d = new byte[]
{
s[3], s[2], s[1], s[0], s[5], s[4], s[7], s[6],
s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15]
};
return new Guid(d);
}
}