关于字节序、比特序,相信已经有很多文章来解释这个事情,本文试图从不同的视角解释这件事情,包括人类阅读者、计算机硬件、C语言开发者、TCP/IP网络、JAVA开发者、编解码开发者。
一、背景
这里再描述一下大端、小端字节序,如下图示:
大端:存储值的高位在低地址,存储值的低位在高地址。比如0x01是该数字的最高字节,但却是存储在0x100,最低的地址;0x67是该数字的最小值的字节,存储在0x103这个最高地址。
小端:存储值的高位在高地址,存储值的低位在低地址。
备注:地址的增长方向默认与人类阅读方向一致,在图中均为从左向右逐渐增大。
比特序和当前机器的字节序保持一致,如果字节序为大端,则比特序也是大端。

二、人类阅读者视角
人类阅读时,从左向右进行阅读,所以先看到数字的高位,最后才能看到数字的低位。所以,人类的阅读顺序,天然是大端顺序。
比如10进制数字1022,转换为二进制是0x03FE,即
1022 = 3 * 16 * 16 + F * 16 + E = 3 * 16 * 16 + 15 * 16 + 14
0x03FE这种表述方式,就是大端顺序,因为0x03作为高位,却在低地址的一侧。
所以,大端顺序是更方便人类阅读和表述的顺序。
三、计算机硬件视角
如上图所示,计算机硬件视角下,字节序由硬件决定,目前是:
x86 处理器为小端字节序;
部分Power等处理器为大端字节序;
ARM、部分Power处理器字节序可配置。
四、C语言开发者视角
因为C语言是非常底层的语言,会直接把内存的实际字节排列返回给开发者,所以开发者需要根据判断硬件的字节序,进行特定的处理
四、TCP/IP网络视角
TCP/IP网络的2端,可能会连接不同的硬件,比如客户端是小端字节序,服务端是大端字节序,这时如果字节序不统一,则无法进行通信。所以,TCP/IP网络中的比特序是固定的。
TCP/IP网络中统一为大端字节序,但比特序为小端比特序。
其中,字节序的转换,依赖不同的语言,可能需要由开发者去转换,比如C语言中,在发送和接收网络数据时需要调用htonl等函数进行字节序转换。但JAVA语言不需要转换。
比特序的转换,则是由网卡完成的。
五、JAVA开发者视角
JAVA对字节序也进行了简化,开发者看到的,统一为大端字节序。所以JAVA开发者轻松很多,只需要按人类正常阅读的方式,处理字节序就可以了
六、编解码开发者视角
对于编解码的开发者,是直接接触字节序和位序的使用者。
比如字段A,在编码协议中,定义为int10,即类型为int,长度为10个bit。如果协议中对某些字段未明确指定字节序,则一般为大端字节序,因为最符合人类的阅读方式。
比如数字300,类型为int10,16进制表示为0x12C,即0x01和0x2C。则编码时,
1.写入0x01,占用2位
2.写入0x2C,占用8位
真实的存储排布为0x012C
参考文章:
1.https://blog.csdn.net/frank_jb/article/details/79027711
2.https://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F
3.https://en.wikipedia.org/wiki/Endianness#Endianness_in_networking
网友评论