我已经使用Elk Scheme interpreter一段时间了,有时会浏览其源代码。
我注意到它在symbol.c中包含以下哈希函数:
int Hash (char const *str, unsigned int len) {
register int h;
register char const *p, *ep;
h = 5 * len;
if (len > 5)
len = 5;
for (p = str, ep = p+len; p < ep; ++p)
h = (h << 2) ^ *p;
return h & 017777777777;
}
源代码中没有任何描述该功能的东西。
此哈希函数有名称吗?
哈希方案是否记录在某处?
答案 0 :(得分:2)
因此,它与经典Fowler-Noll-Vo哈希基本上是相同的算法,但是它没有使用特别选择的素数作为哈希的乘数,而是使用4
(将数字左移2是等于乘以4)。哈希的初始种子值也不同。 5 * len
而不是恒定值。
它只能散列到字符串的前五个字符,这是一个奇怪的选择,我相信作者有充分的理由。
最后一行return h & 017777777777;
也很有趣。假定典型的32位2的补语int
,INT_MAX
,则该八进制常数为。如果计算64位哈希但仅返回低32位,则将看到这种情况,但对于32位类型,则是无操作。也许作者对可移植到具有更大int类型的系统的想法有些偏执?但是,如果仅将它用于以数组长度为模的形式获取返回的哈希值的那个地方,那又何必呢?还是h
原本打算成为unsigned int
,但他们不想使用该类型的全部范围(或者确保当变成带符号的值时,它永远不会为负)?