大小端以及字节序的问题 Endianness
网络字节顺序NBO(Network Byte Order):按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题。
The order in which the bytes of a multi-byte number are transmitted on a network - most significant byte first (as in "big-endian" storage).
主机字节顺序(HBO,Host Byte Order):不同的机器HBO不相同,与CPU设计有关计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。
C#中可以通过BitConverter.IsLittleEndian
Console.WriteLine("BitConverter.IsLittleEndian = {0}", BitConverter.IsLittleEndian);
http://blog.sina.com.cn/s/blog_6a6a80aa01013530.html
http://blog.sina.com.cn/s/blog_6a6a80aa0101352n.html
需要注意的是无符号的整型
uint a=3758205120;
从下图可以看出最高位的字节是 1110 0000 是没有符号位的
namespace System.Net
public class IPAddress
{
public static int HostToNetworkOrder(int host);
public static long HostToNetworkOrder(long host);
public static short HostToNetworkOrder(short host);
}
IPAddress中处理的都是有符号的
int d=2147483647; //2^31-1
//d=2147483648; //int的取值不能超出2147483647,这个赋值溢出了
但是uint就可以赋值: uint d = 2147483648;
===2015年09月23日更新===
字节数组的高低位问题
Console.WriteLine("BitConverter.IsLittleEndian = {0}", BitConverter.IsLittleEndian); const int number = 0x01020304; Console.WriteLine("0x01020304 = {0}", number); var array = BitConverter.GetBytes(number); int index = -1; foreach (byte b in array) { index++; Console.WriteLine("array[{0}] = 0x{1}", index, b.ToString("x2")); }
输出结果是:
BitConverter.IsLittleEndian = True
0x01020304 = 16909060
array[0] = 0x04
array[1] = 0x03
array[2] = 0x02
array[3] = 0x01
0x01020304对应4字节的数字16909060,二进制为 0000 0001,0000 0010,0000 0011,0000 0100
4个字节从高到低: 最高位是0000 0001 最低位是0000 0100
BitConverter.GetBytes(number);
经过BitConverter.GetBytes获取的字节数组,下标小的对应于最低位
BitConverter VS ToString for Hex
Console.WriteLine("BitConverter.IsLittleEndian = {0}", BitConverter.IsLittleEndian); var result = int.MaxValue.ToString("X"); Console.WriteLine(result);//Result: 7FFFFFFF result = BitConverter.ToString(BitConverter.GetBytes(int.MaxValue)); Console.WriteLine(result); //Result: FF-FF-FF-7F
输出结果:
BitConverter.IsLittleEndian = True
7FFFFFFF
FF-FF-FF-7F
解答:
int.MaxValue.ToString("X")
outputs 7FFFFFFF
, that is, the number 2147483647
as a whole.
On the other hand, BitConverter.GetBytes
returns an array of bytes representing 2147483647
in memory. On your machine, this number is stored in little-endian (highest byte last). And BitConverter.ToString
operates separately on each byte, therefore not reordering output to give the same as above, thus preserving the memory order.
However the two values are the same : 7F-FF-FF-FF
for int.MaxValue
, in big-endian, and FF-FF-FF-7F
for BitConverter
, in little-endian. Same number.
字节序的高低位
高位和低位,参看计算器-->程序员,左高右低
比如0x0102 两个字节 01是高位,02是低位
小端字节序:高位在高地址,低位在低地址
大端字节序:高位在低地址,低位在高地址
192.168.1.224
小端字节序:0xc0a801e0 对应数字3232236000
大端字节序:0xe001a8c0 假如按照小端来解析数字的话是3758205120,按照大端来解析首先反转,然后再解析会是3232236000
int.MaxValue.ToString("X")
outputs 7FFFFFFF
, that is, the number 2147483647
as a whole.
On the other hand, BitConverter.GetBytes
returns an array of bytes representing 2147483647
in memory. On your machine, this number is stored in little-endian (highest byte last). And BitConverter.ToString
operates separately on each byte, therefore not reordering output to give the same as above, thus preserving the memory order.
However the two values are the same : 7F-FF-FF-FF
for int.MaxValue
, in big-endian, and FF-FF-FF-7F
for BitConverter
, in little-endian. Same number.
Endianness
These two diagrams show how two computers using different endianness store a 32-bit (four byte) integer with the value of 0x0A0B0C0D. In both cases, the integer is broken into four bytes, 0x0A, 0x0B, 0x0C, and 0x0D, and the bytes are stored in four sequential byte locations in memory, starting with the memory location with address a, then a + 1, a + 2, and a + 3. The difference between big and little endian is the order of the four bytes of the integer being stored.
The left-side diagram shows a computer using big-endian. This starts the storing of the integer with the most-significant byte, 0x0A, at address a, and ends with the least-significant byte, 0x0D, at address a + 3.
The right-side diagram shows a computer using little-endian. This starts the storing of the integer with the least-significant byte, 0x0D, at address a, and ends with the most-significant byte, 0x0A, at address a + 3.
Since each computer uses its same endianness to both store and retrieve the integer, the results will be the same for both computers. Issues may arise when memory is addressed by bytes instead of integers, or when memory contents are transmitted between computers with different endianness.
[Test] public void Test20210413003() { //€ //UTF-8 Encoding: 0xE2 0x82 0xAC //UTF - 16 Encoding: 0x20AC //UTF - 32 Encoding: 0x000020AC string str = "€"; //1252 windows-1252 ANSI Latin 1; Western European (Windows) var array = Encoding.Unicode.GetBytes(str); Console.WriteLine(GetHexString(array)); var array2 = Encoding.BigEndianUnicode.GetBytes(str); Console.WriteLine(GetHexString(array2)); }
小端字节序输出的是AC 20,小端是第一个字节存在最后一个内存, 假设内存地址是a和a+1,那么0x20AC,是把20存在最后一个,然后AC存第一个。
array[0]是0xAC, 这里是a
array[1]是0x20 这里是a+1
大端字节序输出的是20 AC,大端字节序,第一个字节存在第一个内存,
array[0]是0x20 这里是a
array[1]是0xAC 这里是a+1
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了