我目前正在C#/.NET中编写一些内容,涉及在网络数据包中发送无符号16位整数。字节的顺序必须是big-endian。
在位级别上,我对"big-endian"的理解是最高有效位位于末尾,而little-endian则相反。
在字节级别,我的理解是一样的——如果我将一个16位整数转换为组成它的两个8位整数,并且体系结构是小端序,那么我希望最重要的字节在一开始。
然而,BitConverter似乎将具有最小值的字节放在数组的末尾,而不是具有最低有效值的字节,例如
ushort number = 4;
var bytes = BitConverter.GetBytes(number);
Debug.Assert(bytes[BitConverter.IsLittleEndian ? 0 : 1] == 0);
为了清楚起见,如果我的理解是正确的,那么在小端机器上,我希望上面的返回0x00, 0x04
,在大端机器上返回0x04, 0x00
。然而,在我运行.NET 5的小端Windows x86工作站上,它返回0x04, 0x00
甚至有文献记载,他们已经考虑了endianness。发件人:https://learn.microsoft.com/en-us/dotnet/api/system.bitconverter.getbytes?view=net-5.0
GetBytes方法返回的数组中字节的顺序取决于计算机体系结构是小端序还是大端序。
我是愚蠢还是这似乎是错误的行为?
我真是太傻了。正如@mjwills所指出的,以及微软的文档所解释的那样(https://learn.microsoft.com/en-us/dotnet/api/system.bitconverter.islittleendian?view=net-5.0#备注(:
"Big endian"表示最高有效字节位于单词的左端"Little endian"表示最高有效字节位于单词的右端。
维基百科有一个稍微好一点的解释:
大端系统将字的最高有效字节存储在最小的内存地址,将最低有效字节存储到最大的地址。相反,小端序系统将最低有效字节存储在最小地址。
因此,如果您想象内存地址,则将值为4的16位整数转换为:
地址 | 0x00 | 0x01|
---|---|---|
Little-endian | 0x04 | 0x00 |
Big endian | 0x00 | 0x04 |