字节序(byte order)定义了多个字节组成的数据在内存中存放的顺序。它主要分为两种:
- 大端序(big endian):高位字节存放在低地址,低位字节存放在高地址。
- 小端序(little endian):低位字节存放在低地址,高位字节存放在高地址。
大端序的存储方式更符合人的阅读习惯,但是小端序在某些场景下的性能会更高一些。所以不同的机器体系结构采用的字节序也不同。
例如,整数0x1234在两种字节序下的存储:
大端序:
地址 0 1 2 3
数据 12 34
小端序:
地址 0 1 2 3
数据 34 12
Golang 可以通过内置的函数来操作字节序:
- binary.BigEndian:判断是否大端序
- binary.LittleEndian:判断是否小端序
- binary.ByteOrder:返回主机字节序
- binary.BigToHost/ binary.LittleToHost:主机序到大/小端序的转换
- binary.BigToLittle/ binary.LittleToBig:大/小端序相互转换
例如:
// 确定主机字节序
endian := binary.ByteOrder
// 32位整数0x12345678
var num int32 = 0x12345678
// 大端序转主机序
bigEndian := binary.BigToHost(num)
// 小端序转主机序
littleEndian := binary.LittleToHost(num)
// 大端序和小端序相互转换
bigToLittle := binary.BigToLittle(num)
littleToBig := binary.LittleToBig(num)
所以字节序主要影响多字节数据在内存中的存放方式。不同的机器体系结构采用不同的字节序会带来数据不兼容的问题。
Golang 提供的 binary 包可以方便地在不同字节序间转换数据,这使我们在设计网络协议,序列化与反序列化,加密算法等场景下更容易考虑字节序的影响。
字节序作为连接软件与硬件的桥梁,理解它可以让我们在架构与接口的设计上思考更为全面与深入。