c - 高效的大端字节数组到 C 中的本机整数转换
问题描述
1) 是否有任何编译器内置指令,或用于 x86、ARM 或其他架构的汇编指令,它们将采用大端字节数组(2 字节 -> uint16_t,4 字节 -> uint32_t,8 字节 -> uint64_t)并将其转换为本机字节序的无符号整数(大、小、混合)。
2)是否还有任何内置函数或指令来执行逆转换(整数到大端字节数组)。
天真的原生 C 函数将是:
static inline void put_be16(uint8_t a[static sizeof(uint16_t)], uint16_t val)
{
a[0] = (val >> 8) & 0xff;
a[1] = val & 0xff;
}
static inline uint16_t get_be16(uint8_t const a[static sizeof(uint16_t)])
{
return (a[0] << 8) | a[1];
}
这些用于从入站网络数据包中读取无符号整数,并对无符号整数进行编码以用于出站网络数据包。
解决方案必须防止或减轻未对齐的内存访问。
编辑:并且希望高效,所以直接在输入/输出缓冲区上运行的东西是我真正想要的。
解决方案
至于C方面,我想这已经被问过了。我通过快速搜索找到了这个: 将 Little Endian 转换为 Big Endian
您可以使用 htonl()、htons() 和相关的,它们将与已知的大端格式相互转换。您还可以使用联合从 int 或 long 等中提取单个字节,如下所示:
union extract_byte_val {
long long_val;
uint8_t bytes_val[sizeof(long)];
}
例如:
long x = 128;
union extract_byte_val eb;
eb.long_val = htonl(x);
eb.bytes_val 现在是 {0, 0, 0, 128},因为 eb.long_val 是 bug-endian。
推荐阅读
- java - 没有这样的列:MariaDB 查询中的 id
- powershell - 如何使用 PowerShell 从任务计划程序中删除文件夹?
- linux - 文件描述符处于阻塞模式,但 read() 没有阻塞
- hyperledger-fabric - 从私人收藏中添加数据和查询的示例代码
- python - 我无法让 ipython 控制台在 spyder 中播放声音
- python - 为什么我无法在 matplotlib.pyplot 直方图中使用相同的数据集后在图表中使用它?
- c - 如何根据使用的选项更改大小写
- android - 如何等待firebase数据获取完成并在react-native中获取不是承诺的值?
- firebase - 有没有一种简单的方法可以在 Flutter 中本地缓存 Cloud Firestore 文档(不是离线持久性)?
- android - 无法从相机返回的图像中获取正确的像素