c++ - 您如何编写(可移植的)反向网络字节顺序?

标签 c++ c portability endianness

背景

在设计二进制文件格式时,一般建议按照网络字节序写入整数。为此,有像 htonhl() 这样的宏。但是对于WAV这样的格式,实际上使用的是little endian格式。

问题

无论代码运行的 CPU 是大端架构还是小端架构,您如何可移植地写入小端值?(想法:标准宏 ntohl() htonl() 以某种方式“反向”使用?或者如果代码在小端或大端 CPU 上运行并选择适当的代码路径,代码是否应该只测试运行时?)

所以问题实际上与文件格式无关,文件格式只是一个例子。它可以是需要“在线”小端字节序的任何类型的序列化,例如(异端)网络协议(protocol)。

最佳答案

警告:这仅适用于无符号整数,因为有符号右移是实现定义的并且可能导致漏洞 (https://stackoverflow.com/a/7522498/395029)

C 已经提供了对主机字节顺序的抽象: number † 或 int†。

以给定的字节序生成输出可以通过不试图变得聪明来轻松完成:只需将数字解释为数字并使用位移位来提取每个字节:

uint32_t value;
uint8_t lolo = (value >> 0) & 0xFF;
uint8_t lohi = (value >> 8) & 0xFF;
uint8_t hilo = (value >> 16) & 0xFF;
uint8_t hihi = (value >> 24) & 0xFF;

然后您只需按照您想要的任何顺序写入字节即可。

当您将具有某种字节顺序的字节序列作为输入时,您可以通过再次使用位操作构造数字,以主机的字节顺序重建它们:

uint32_t value = (hihi << 24)
               | (hilo << 16)
               | (lohi << 8)
               | (lolo << 0);

† 只有作为字节序列的数字表示才具有字节顺序;数字(即数量)不会。

关于c++ - 您如何编写(可移植的)反向网络字节顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16008879/

相关文章:

c++ - 强制内部 API 的调用者使用固定大小类型?

c++ - 以安全的 C++ 方式获取 FILE*

c++ - 在没有附加库的情况下在标准 C/C++ 中解析 XML

c - float* 类型的变量应该指向单个 float 还是一系列 float ?

c - 从 C 中的 typedef 结构对数组进行排序

c - 当时间过去时真正杀死当前进程

sql - JDBC SQL :Where is the detailed specification?

python - 如何尽可能忽略GUI而不渲染APP较少的GUI开发人员友好

c++ - 可克隆类层次结构和 unique_ptr

c++ - 如何使用 natvis Visual Studio C++ 调试器可视化工具对单一类型进行多个列表扩展