uint32_t值对的交换哈希函数

pla*_*cel 8 c++ algorithm hash uint32

我需要创建一个对的唯一标识符的快速,简单的哈希函数uint32_t值-因此对于相同的散列值(2,7)(7,2).

任何的想法?

pla*_*cel 6

要回答我自己的问题,解决方案是:

uint64_t hash(uint32_t x, uint32_t y)
{
    const uint64_t a = static_cast<uint64_t>(x);
    const uint64_t b = static_cast<uint64_t>(y);

    if (x < y) return (b << 32) | a;
    else return (a << 32) | b;
}
Run Code Online (Sandbox Code Playgroud)

哪些可以改进为无分支版本

uint64_t hash(uint32_t x, uint32_t y)
{
    const uint64_t a = static_cast<uint64_t>(x);
    const uint64_t b = static_cast<uint64_t>(y);

    const uint64_t h0 = (b << 32) | a;
    const uint64_t h1 = (a << 32) | b;

    return (x < y) ? h0 : h1; // conditional move (CMOV) instruction
}
Run Code Online (Sandbox Code Playgroud)

这些方法是完美的哈希函数 - 它们保证零冲突.但是,它们的缺点是您无法对上面的值进行哈希处理2^32 - 1.

  • 我喜欢转移的想法,它是自然的,没有必要证明唯一性.如果你想处理2 ^ 32以上的值,你可以返回一个字符串作为唯一标识符,你可以保留一个特殊的符号来分隔哈希的两个部分(更改表示基数大于10也是一个好主意) (2认同)
  • @plasmacel signed int右移是实现定义的,你的`max << 32`调用未定义的行为(因为你移动的数量> = datatype大小).只有在`|`之后才能保证将结果转换为`uint64_t`.在实践中,无论如何你的编译器都在进行64位计算,但这不能肯定. (2认同)