图片来源: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 .. ); }
参考:
- https://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F
- https://serverfault.com/questions/163487/how-to-tell-if-a-linux-system-is-big-endian-or-little-endian
- https://zh.cppreference.com/w/cpp/language/union
- https://stackoverflow.com/questions/8978935/detecting-endianness
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
一条评论 “字节序”