字节序,指的就是在计算机中存储的数据字节顺序,分为大端字节序和小端字节序。先看看以下代码,直观感受一下什么叫字节序。
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
buf := bytes.NewBuffer([]byte{})
var data int32 = 258
if err := binary.Write(buf, binary.BigEndian, data); err != nil {
panic(err)
}
var mem int32
if err := binary.Read(buf, binary.BigEndian, &mem); err != nil {
panic(err)
}
// [0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 1 - 0 0 0 0 0 0 1 0]
bitPrint(mem)
if err := binary.Write(buf, binary.BigEndian, data); err != nil {
panic(err)
}
var mem2 int32
if err := binary.Read(buf, binary.LittleEndian, &mem2); err != nil {
panic(err)
}
// [0 0 0 0 0 0 1 0 - 0 0 0 0 0 0 0 1 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0]
bitPrint(mem2)
}
func bitPrint(mem int32) {
buff := make([]string, 35)
for b := 34; b >= 0; b-- {
if b%9 == 8 {
buff[b] = "-"
} else {
if mem%2 == 1 {
buff[b] = "1"
} else {
buff[b] = "0"
}
mem /= 2
}
}
fmt.Printf("%s\n", buff)
}
以上示例,均以大端字节序写入相同数据,读取时分别使用了大端和小端字节序,其中大端的结果是:
[0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 1 - 0 0 0 0 0 0 1 0]
小端的结果是:
[0 0 0 0 0 0 1 0 - 0 0 0 0 0 0 0 1 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0]
这两个结果以-
符号对每个字节进行了分隔。很明显,两个结果的字节顺序刚好相反。其中,大端的结果转为十进制就是 258,跟我们写入的数据一致;而小端的结果则显然是不对的。
大端字节序更符合人类习惯,跟我们平时用的十进制数据一样,高位在左,低位在右;而小端字节序则更适合计算机处理,计算机只会按顺序读取字节,先读取第一个字节,再依次读取其余字节,从低位开始效率比较高,因此低位在右,也就是小端字节序。
之前看到过字节序的一些内容,有些老旧系统还是使用小端字节序的,但现在大部分都用的大端字节序,一般情况下也不需要关注这些。更深入的内容有待以后学习~