前段时间在做socket编程时,遇到了处理包头字节数据的问题,字节转为整数时需要反转,当时不太明白,于是查了一些资料,了解了一下关于计算机系统字节顺序问题,把这些资料保存一下。
关于端(endian)的起源
“endian”一词来源于乔纳森·斯威夫特的小说格列佛游记。小说中,小人国为水煮蛋该从大的一端(Big-End)剥开还是小的一端(Little-End)剥开而争论,争论的双方分别被称为“大端派”和“小端派”。以下是1726年关于大小端之争历史的描述:
“我下面要告诉你的是,Lilliput和Blefuscu这两大强国在过去36个月里一直在苦战。战争开始是由于以下的原因:我们大家都认为,吃鸡蛋前,原始的方法是打破鸡蛋较大的一端,可是当今皇帝的祖父小时候吃鸡蛋,一次按古法打鸡蛋时碰巧将一个手指弄破了。因此他的父亲,当时的皇帝,就下了一道敕令,命令全体臣民吃鸡蛋时打破鸡蛋较小的一端,违令者重罚。老百姓们对这项命令极其反感。历史告诉我们,由此曾经发生过6次叛乱,其中一个皇帝送了命,另一个丢了王位。这些叛乱大多都是由Blefuscu的国王大臣们煽动起来的。叛乱平息后,流亡的人总是逃到那个帝国去寻求避难。据估计,先后几次有11000人情愿受死也不肯去打破鸡蛋较小的一端。关于这一争端,曾出版过几百本大部著作,不过大端派的书一直是受禁的,法律也规定该派任何人不得做官。”1980年,Danny Cohen,一位网络协议的早期开发者,在其著名的论文"On Holy Wars and a Plea for Peace"中,为平息一场关于字节该以什么样的顺序传送的争论,而第一次引用了该词。【摘自《深入了解计算机系统》】
小端序
小端序(英:little-endian)或称小尾序。
- 数据以8bit为单位:
地址增长方向 → | |||||
0x0D | 0x0C | 0x0B | 0x0A |
最低位字节是0x0D 存储在最低的内存地址处。后面字节依次存在后面的地址处。
大端序
大端序(英:big-endian)或称大尾序。
- 数据以8bit为单位:
地址增长方向 → | |||||
0x0A | 0x0B | 0x0C | 0x0D |
示例中,最高位字节是0x0A 存储在最低的内存地址处。下一个字节0x0B存在后面的地址处。正类似于十六进制字节从左到右的阅读顺序。
示例代码:
void ByteTest()
{
//十进制:12345,十六进制表示为:0x00003039
byte[] bytes = BitConverter.GetBytes(12345);
for (int i = 0; i < bytes.Length; i++)
Console.WriteLine("byte[{0}]={1}",i,bytes[i]);
//output:
//byte[0]=57 Hex:0x39
//byte[1]=48 Hex:0x30
//byte[2]=0
//byte[3]=0
//转换为十进制
int result = BitConverter.ToInt32(bytes,0);
Console.WriteLine(result);
//output:
//12345
}
在网络编程中,包头中的字节数据,在进行转换前,需要反转字节数组。