为啥 Guid.ToString("n") 与从相同 guid 的字节数组生成的十六进制字符串不同?
Posted
技术标签:
【中文标题】为啥 Guid.ToString("n") 与从相同 guid 的字节数组生成的十六进制字符串不同?【英文标题】:Why isn't Guid.ToString("n") the same as a hex string generated from a byte array of the same guid?为什么 Guid.ToString("n") 与从相同 guid 的字节数组生成的十六进制字符串不同? 【发布时间】:2011-03-20 05:29:23 【问题描述】:考虑以下单元测试:
[TestMethod]
public void TestByteToString()
var guid = new Guid("61772f3ae5de5f4a8577eb1003c5c054");
var guidString = guid.ToString("n");
var byteString = ToHexString(guid.ToByteArray());
Assert.AreEqual(guidString, byteString);
private String ToHexString(Byte[] bytes)
var hex = new StringBuilder(bytes.Length * 2);
foreach(var b in bytes)
hex.AppendFormat("0:x2", b);
return hex.ToString();
结果如下:
Assert.AreEqual failed. Expected:<61772f3ae5de5f4a8577eb1003c5c054>. Actual:<3a2f7761dee54a5f8577eb1003c5c054>.
【问题讨论】:
【参考方案1】:嗯,它们是相同的,在前 4 个字节之后。前四个是相同的,只是顺序相反。
基本上,当从字符串创建时,它被假定为“big-endian”格式:左边的最高字节。但是,当在内部存储时(在 Intel 机器上),字节按“小端”排序:右边的最高字节。
【讨论】:
【参考方案2】:如果比较结果,可以看到前三组是相反的:
61 77 2f 3a e5 de 5f 4a 8577eb1003c5c054 3a 2f 77 61 de e5 4a 5f 8577eb1003c5c054那是因为在GUID structure中,这3个组被定义为DWORD
和两个WORD
s而不是字节:
0x00000000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
所以在内存中,Intel 处理器以 Little-endian 顺序存储它们(最重要的字节在最后)。
【讨论】:
【参考方案3】:GUID 的结构如下:
int a
short b
short c
byte[8] d
因此,对于a
表示的部分,您的代码会将字节反转。所有其他部分均已正确转换。
【讨论】:
为什么b
和c
也不能颠倒过来?
@SebastianGodelet - 因为他们是short
而不是int
。
我认为大于一个字节的所有内容都受字节序的影响:short s = 0xaf21;
可以存储:|af|21|或 |21|af|
@SebastianGodelet - 可能,但字节序通常在 int
级别。
不是想变得讨厌,但我认为这里有一点误解...... 16 位整数,c.f. System.Int16
也受字节序的影响,例如: Unicode 传输编码:UTF-16LE 和 UTF-16BE,但仅限于:UTF-8,以上是关于为啥 Guid.ToString("n") 与从相同 guid 的字节数组生成的十六进制字符串不同?的主要内容,如果未能解决你的问题,请参考以下文章