大端和小端
big endian(大端法)是指低地址存放最高有效字节(MSB),而little endian(小端法)则是低地址存放最低有效字节(LSB)。
通过文字理解可能比较抽象,下面用图像加以说明。下图是“0x12345678在两种字节序中的存储顺序”:
Big Endian
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 12 | 34 | 56 | 78 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
说明:上面是0x12345678对应big endian的存储方式。
(01) 0x12345678是int整数,它共有4个字节:分别是0x12, 0x34, 0x56, 0x78;其中,0x12是最高有效字节,0x78是最低有效字节。int占4个字节,这个是常识;0x12是十六进制的表示方式,0x12对应的二进制是00010010,正好是8位,也就是1个字节;因此0x12, 0x34, 0x56, 0x78共是4个字节。
(02) big endian是将最高有效字节存储在低地址中,因为就是0x12(最高有效地址),存在低地址;那么,从低往高地址依次存放0x12 --> 0x34 --> 0x56 --> 0x78。也就是上面图像中的存储方式。
Little Endian
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 78 | 56 | 34 | 12 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
说明:上面是0x12345678对应little endian的存储方式。
(01) 0x12345678是int整数,它共有4个字节:分别是0x12, 0x34, 0x56, 0x78;其中,0x12是最高有效字节,0x78是最低有效字节。
(02) little endian是将最低有效字节存储在低地址中,因为就是0x78(最低有效地址),存在低地址;从低往高地址依次存放0x78 --> 0x56 --> 0x34 --> 0x12。也就是上面图像中的存储方式。
big endian 和 little endian判断方式
下面,我们通过示例程序来判断CPU是大端存储还是小端存储。
源码如下(endian.c):
void main() {
int i = 0x12345678;
char* pc = (char*)&i;
if (*pc == 0x12) {
printf("Big Endian\n");
} else if (*pc == 0x78) {
printf("Little Endian\n");
}
}
我在ubuntu12.04系统下,运行的结果是“Little Endian”。
ProtocolBuffer在写入字节流时,是按大端方式写入的
经测试C#在Intel Windows10 环境下是按小端存储数据的。
在写入proto的CodeOutputStream中,是按大端方式写入字节流的,所以网络中传输的是大端字节序。
System.Text.Encoding.UTF8.GetBytes(xxxxx),返回的字节序是大端的。