This site对旋转散列的描述如下。

unsigned rot_hash ( void *key, int len )
{
    unsigned char *p = key;
    unsigned h = 0;
    int i;

    for ( i = 0; i < len; i++ )
        h = ( h << 4 ) ^ ( h >> 28 ) ^ p[i];

   return h;
}

这里的返回值是32位。但是,我想返回一个16位散列值。为此,在循环中指定h是否正确?考虑将h声明为16位整数。
for ( i = 0; i < len; i++ )
          h = ( h << 4 ) ^ ( h >> 12 ) ^ p[i];

最佳答案

最好保留大散列,并且只在返回时截断,例如:

for ( i = 0; i < len; i++ )
    h = ( h << 4 ) ^ ( h >> 28 ) ^ p[i];

return h & 0xffff;

移位常数4和28可能不是最好的(简而言之:因为它们有一个公约数)
在一些实验之后,我来到下面的哈希函数,其目的是在较低的比特中具有最大熵(这样就可以使用两个表大小的幂)(这是在Wakkerbot中使用的):
unsigned hash_mem(void *dat, size_t len)
{
unsigned char *str = (unsigned char*) dat;
unsigned val=0;
size_t idx;

for(idx=0; idx < len; idx++ )   {
        val ^= (val >> 2) ^ (val << 5) ^ (val << 13) ^ str[idx] ^ 0x80001801;
        }
return val;
}

严格来说,不需要使用0x80001801的额外干扰,但如果哈希项具有长的公共前缀,则会有帮助。如果这些前缀由0x0值组成,也会有帮助。

关于c - 旋转哈希16位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10497037/

10-12 03:16