大端(Big Endian)和小端(Little Endian)是指在存储和传输数据时,多字节数据的高位字节和低位字节的排列顺序。
以一个16位整数0x1234为例:
大端模式:高位字节0x12存储在低地址,低位字节0x34存储在高地址。
小端模式:高位字节0x34存储在低地址,低位字节0x12存储在高地址。
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
var i uint32 = 1234
// 小端
b := make([]byte, 4)
binary.LittleEndian.PutUint32(b, i)
fmt.Printf("LittleEndian(%d) :", i)
for _, bin := range b {
fmt.Printf("%02X ", bin)
}
fmt.Printf("\n")
//大端
fmt.Printf("BigEndian(%d) :", i)
binary.BigEndian.PutUint32(b, i)
for _, bin := range b {
fmt.Printf("%02X ", bin)
}
fmt.Printf("\n")
//[]byte 2 uint32
bytesBuffer := bytes.NewBuffer(b)
var j uint32
binary.Read(bytesBuffer, binary.BigEndian, &j)
fmt.Println("j = ", j)
}
运行结果
PS G:\example> go run .\main.go
LittleEndian(1234) :D2 04 00 00
BigEndian(1234) :00 00 04 D2
j = 1234
因为不同的使用场景下,效率是不一样。
对于网络传输,使用的就是大字端。为什么?因为,早年设备的缓存很小,先接收高字节能快速的判断报文信息:包长度(需要准备多大缓存)、地址范围(IP地址是从前到后匹配的)。在性能不是很好的设备上,高字节在先确实是会更快一些。
对于一个加法器,选择的是小字端。为什么?因为,加法是从低位到高位开始加,一旦有进位,就直接送到下一位,设计就很简单。