Endian 是计算机领域中表示“字节排列顺序”的术语,中文通常译为端序或字节序。当一个数据由多个字节组成时,Endian 用来说明这些字节在内存、文件或网络数据中的先后位置。最常见的两种形式是 Big Endian(大端序)和 Little Endian(小端序)。
简单来说,Endian 不是在说明一个数“是多少”,而是在说明这个数的不同字节“怎么排”。同一个整数在大端和小端中代表的数值可以完全相同,只是它在内存或数据流中的排列方式不同。因此,看到 endian 这个词时,通常要继续确认它指的是 big endian 还是 little endian。
Endian到底是什么意思?
计算机通常以字节为单位处理数据,一个字节包含 8 个二进制位。像字符这样的数据可能只占一个字节,但整数、浮点数、时间戳和内存地址等数据,往往由 2 个、4 个或更多字节组成。
例如,十六进制数 0x12345678 由四个字节组成:
- 0x12:最高有效字节
- 0x34:次高有效字节
- 0x56:次低有效字节
- 0x78:最低有效字节
Endian 关注的就是这四个字节在连续存储空间中的排列顺序。这里的“高”与“低”指的是数值权重,不是内存地址高低,也不是字节在屏幕上的上下位置。
为什么同一个数会有大端和小端两种排列方式?
因为多字节数据需要被拆分后放入连续的字节位置,而不同处理器、操作系统或数据格式可以采用不同的约定。假设内存地址从低到高依次增加,数值 0x12345678 的排列可以表示为:
| 端序 | 低地址到高地址的字节顺序 | 排列特点 |
|---|---|---|
| 大端序 Big Endian | 12 34 56 78 | 最高有效字节放在低地址 |
| 小端序 Little Endian | 78 56 34 12 | 最低有效字节放在低地址 |
大端序的排列方式与人们书写十六进制数字的顺序更接近:先看到最高位,再看到最低位。小端序则把最低有效字节放在最前面。无论采用哪种排列,重新按照对应规则读取后,得到的数值仍然是 0x12345678。
“Big Endian”和“Little Endian”这两个名称,通常被认为与文学作品中关于“大端剥蛋”与“小端剥蛋”的争论有关。后来,这组说法被计算机领域借来描述数据排列顺序。这里的“端”不是数据的一端被截断,而是指一个多字节数据从哪一端开始排列。
Endian和字节序、位序是一回事吗?
在大多数技术文档中,Endian 主要讨论的是字节序,也就是多个字节之间的顺序。因此,“Endian”“端序”和“字节序”经常被当作近似同义词使用。不过,Endian 不应直接等同于位序。
字节序关注字节之间的顺序
以 0x1234 为例,它由 0x12 和 0x34 两个字节组成。大端序通常写为 12 34,小端序通常写为 34 12。这里变化的是两个字节的排列位置。
位序关注一个字节内部的位如何解释
一个字节 0x12 内部还包含 8 个二进制位。讨论这些位在寄存器、总线或通信协议中的传输顺序时,涉及的是位序、位编号方式或比特传输顺序。它与大端、小端的字节排列不是同一个问题。
因此,看到某个资料说“采用小端”,通常只能先理解为“多字节数据按小端字节序排列”,不能据此推断每个字节内部的比特一定按照某种物理方向传输。
什么时候必须区分 Endian?
如果数据只在同一程序、同一运行环境中使用,程序通常会按照当前平台的规则完成读写,开发者未必需要直接观察每个字节。但在以下情况下,Endian 就会成为必须明确的概念:
- 读取二进制文件:文件格式可能规定整数、长度字段或偏移量采用大端或小端。如果读取程序使用了相反规则,数值就会被解析错误。
- 网络通信:许多互联网协议中的整数采用约定好的网络字节序,常见网络字节序为大端序。发送端和接收端需要遵循协议规定,而不能只按本机习惯处理。
- 跨平台交换数据:不同处理器或系统可能使用不同的默认端序,数据格式如果没有明确规定端序,就容易出现兼容问题。
- 调用外部接口:程序与设备、操作系统接口或其他语言交换二进制结构体时,字段的字节排列、长度和对齐方式都可能影响结果。
- 查看内存和调试数据:调试器展示的字节序列与源代码中的整数写法可能不同,理解端序有助于判断内存中的原始内容。
判断时可以先问两个问题:第一,数据是否由多个字节组成;第二,数据是否需要在不同程序、平台或设备之间交换。如果只是处理单个字节,例如一个 0 到 255 的数值,通常不存在大端或小端的区别;如果是 16 位、32 位或 64 位数据,就需要确认排列规则。
Endian和“数字写法”为什么看起来不一样?
人们书写 0x12345678 时,通常从左到右按照最高位到最低位排列。这是数字的表示法。内存则是按地址保存一个个字节,地址从低到高排列时,具体先放哪个字节由端序决定。
因此,程序员在源代码中看到的数字顺序,并不一定等于内存查看工具显示的字节顺序。比如小端机器上,变量的值仍然可以写作 0x12345678,但从低地址开始查看原始内存时,可能依次看到 78、56、34、12。两者并不矛盾:前者是在表达数值,后者是在展示存储布局。
同样,文本内容也不能简单按“字符串是大端还是小端”来理解。普通单字节字符通常不存在这种字节排列问题;某些多字节字符编码或编码文件格式可能规定端序,这时要按照具体编码和文件规范判断,而不能仅凭“文字由多个字节组成”就直接套用大小端结论。
看到 Endian 时应该如何理解?
可以把它概括为一句话:Endian 描述的是多字节数据中,各个字节按照什么顺序存放或传输。如果资料写的是 Big Endian,通常表示最高有效字节在前;如果写的是 Little Endian,通常表示最低有效字节在前。
实际阅读文档时,还应结合数据的边界和规则一起看:字段占几个字节、低地址如何定义、协议是否指定网络字节序、文件头是否包含端序标记,以及读取方是否需要进行字节交换。只有在这些条件明确后,才能准确判断一串十六进制字节代表什么数值。