字节序

图片来源:https://www.pixiv.net/artworks/101597578

大端序(网络序):高字节在低地址

小端序:高字节在高地址

大端序(图来自维基百科)
小端序(图来自维基百科)

判断当前运行环境的字节序

C++

通过自定义变量值判断

#include <cstdint>

constexpr bool isLittleEndian() {
    const uint32_t a = 0x0A0B0C0Du;
    return *(uint8_t*)(&a) == 0x0Du;
}

另外,C++标准中对于结构体的非活跃成员的访问属于未定义行为,虽然使用g++编译运行都没问题,但以下代码不能保证运行结果正确

#include <cstdint>

constexpr bool isLittleEndian() {
    const union {
        uint32_t allbyte;
        uint8_t byte_arr[sizeof(allbyte)];
    } data = { 0x0A0B0C0D } // 初始化第一个成员;
    // 此时访问data.byte_arr属于未定义行为
    return data.byte_arr[0] == 0x0D;
}

使用GCC宏

constexpr bool isLittleEndian() {
    return __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
}

C++20标准库已经内置了字节序相关变量

#include <bit>

constexpr bool isLittleEndian() {
    return std::endian::native == std::endian::little;
}

Shell

echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6 

输出“1”则为小端序,输出“0”则为大端序

查看CPU参数

CPU相关信息里的“Byte Order”字段有字节序信息

lscpu | grep Endian
Byte Order:                      Little Endian

转换

Linux函数

#include <arpa/inet.h>

// 本机序转网络序
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);

// 网络序转本机序
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

Shell

反转字节序,输入输出均为十进制数

function byterev(){ printf "%d" 0x$(printf "%08x" $@ | tac -rs .. ); }

参考:

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

一条评论 “字节序”