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/