主机字节序

计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)

  • big endian
    高位字节在前,低位字节在后

  • little endian
    低位字节在前,高位字节在后

为什么会有小端字节序

计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。
举例:0x1234

如果小端 result = 0x34 + 0x12 * 256
如果是大端 result = 0x12 * 256 + 0x34 这时必须知道当前每个字节位于第几个才能知道幂

但是,人类还是习惯读写大端字节序。所以,除了计算机的内部处理,其他的场合几乎都是大端字节序,比如网络传输和文件储存

Go 判断机器是大端还是小端

import (
    "fmt"
    "unsafe"
)
// 判断主机是大端字节序还是小端字节序
func main(){
    fmt.Println(seq())
}
func seq() string {
    var k int32 = 0x12345678
    u := unsafe.Pointer(&k)
    pb := (*byte)(u)
    if *pb == 0x12 {
        return "Big Endding"
    }
    return "Little Endding"
}

C 判断机器是大端还是小端

#include <stdio.h>

int byteOrder(){
    union {
        short value;
        char bytes[2];
    } u;
    u.value = 0x0102;
    if (u.bytes[0] == 1 && u.bytes[1] == 2) {
        return 1;
    } else if (u.bytes[0] == 2 && u.bytes[1] == 1) {
        return 2;
    } else {
        return -1;
    }
}

int main(){
    int res = byteOrder();
    switch(res){
        case 1:
            printf("Big Endian");
            break;
        case 2:
            printf("Litter Endian");
            break;
        default:
            printf("unknow");
    }
    return 0;
}

网络字节序

网络中的字节顺序,沿用我们的读写习惯,高字节在左边,因此为大端序
c 验证

#include <stdio.h>
#include <stdlib.h>

int main(){
    short int a = 0x1234;
    short int p = htons(a);
    char *ptr = (char *)(&p);
    printf("%x",*ptr);
    return 0;
}

得到结果是 12, 可以验证网络字节序为大端字节序

注意

  • 因为int型数据,一个数据占多个字节,所以会产生字节序的问题,故需要调用htons,ntohs进行统一。

  • 当数据时字符串数组,此时,报文数据就是一个字节,一个字节的存放,不存在字节的问题,也不需要调用htons,ntohs进行转换。

文档更新时间: 2021-01-25 20:42   作者:周国强