首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何更改128位数字的字节顺序

如何更改128位数字的字节顺序
EN

Stack Overflow用户
提问于 2011-11-04 12:09:42
回答 5查看 4.6K关注 0票数 6

我有一个无符号字符数组,它表示网络字节顺序中的128位数字。我该如何有效地将其转换为主机字节顺序(在本例中为x86_64)?

在endian.h中似乎没有任何可用的宏,并且我试图独立转换高64位和低64位的尝试也不起作用。我发现唯一有效的方法是像这样的循环:

代码语言:javascript
运行
复制
unsigned __int128 num = 0;
for (int i = 0; i < 16; i++) {
    num = (num << 8) | byte[i];
}

我最终完成了以下操作:

代码语言:javascript
运行
复制
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 */
EN

Stack Overflow用户

发布于 2021-12-01 02:23:22

这是一个基于Joshua的建议的实现,即分别交换64位块的字节,然后交换64位块:

代码语言:javascript
运行
复制
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函数将编译为以下程序集:

代码语言:javascript
运行
复制
mov     rax, rsi
bswap   rdi
bswap   rax
mov     rdx, rdi
ret

现代编译器能很好地“看透”你的代码,这让我印象深刻!

票数 0
EN
查看全部 5 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8004790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档