我有一个无符号字符数组,它表示网络字节顺序中的128位数字。我该如何有效地将其转换为主机字节顺序(在本例中为x86_64)?
在endian.h中似乎没有任何可用的宏,并且我试图独立转换高64位和低64位的尝试也不起作用。我发现唯一有效的方法是像这样的循环:
unsigned __int128 num = 0;
for (int i = 0; i < 16; i++) {
num = (num << 8) | byte[i];
}我最终完成了以下操作:
union {
unsigned char b[MD5_DIGEST_LENGTH];
uint64_t d[2];
unsigned __int128 q;
} digest;
MD5((const unsigned char *)str, length, digest.b);
uint64_t tmp = digest.d[0];
digest.d[0] = be64toh(digest.d[1]);
digest.d[1] = be64toh(tmp);
/* digest.q is now in native byte order */发布于 2021-12-01 02:23:22
这是一个基于Joshua的建议的实现,即分别交换64位块的字节,然后交换64位块:
uint64_t flip(uint64_t n)
{
return ((n & 0xFF00000000000000u) >> 56u) |
((n & 0x00FF000000000000u) >> 40u) |
((n & 0x0000FF0000000000u) >> 24u) |
((n & 0x000000FF00000000u) >> 8u) |
((n & 0x00000000FF000000u) << 8u) |
((n & 0x0000000000FF0000u) << 24u) |
((n & 0x000000000000FF00u) << 40u) |
((n & 0x00000000000000FFu) << 56u);
}
unsigned __int128 swap(unsigned __int128 n)
{
unsigned __int128 m;
const uint64_t* src = (const uint64_t*)(&n);
uint64_t* dest = (uint64_t*)(&m);
dest[1] = flip(src[0]);
dest[0] = flip(src[1]);
return m;
}如果使用C++,请用reinterpret_cast替换上面的C样式转换。
根据Godbolt的说法,对于Clang 12,-O3,swap函数将编译为以下程序集:
mov rax, rsi
bswap rdi
bswap rax
mov rdx, rdi
ret现代编译器能很好地“看透”你的代码,这让我印象深刻!
https://stackoverflow.com/questions/8004790
复制相似问题