我正在研究javascript中hasmap的哈希字符串函数。并且查看我在网络上找到的这段代码,我不确定该功能是否正确:
HashMap._hashString = function(string) {
var hash = 5381;
for (var i=0; i<string.length; i++) {
hash = (hash << 5) + hash + string.charCodeAt(i);
hash = hash & hash;
}
//Reduce the chance of collisions by incorporating the string length,
//and randomize the hashes to prevent malicious collisions.
return hash ^ string.length ^ this._secret;
};
拥有这条线是否有意义?
hash = hash & hash;
在这行代码中:
return hash ^ string.length ^ this._secret;
据我所知,添加字符串的长度作为要评估的哈希的因素将有助于处理冲突,但为什么我会使用XOR操作添加此因子?为什么不使用任何其他位运算符?
我也正在阅读有关这篇文章的内容,以便更多地了解哈希算法:
答案 0 :(得分:1)
拥有这条线是否有意义?
hash = hash & hash;
该行的目的是将值限制为32位范围。 hash & hash
看似无操作,但应用按位运算符会剪切任何溢出。它给出了与此相同的结果:
hash = hash & 0xFFFFFFFF
在这行代码中:
return hash ^ string.length ^ this._secret;
据我所知,添加字符串的长度作为要评估的哈希的因素将有助于处理冲突,但为什么我会使用XOR操作添加此因子?为什么不使用任何其他位运算符?
使用&
或|
您将丢失信息:相同长度的不同输入会有更高的碰撞机会。特别是,长度为2的幂&
将是灾难性的,因为它只能产生2个不同的值(长度本身或零)。或者|
长度大多为1位(如0xffff):这将再次限制可能的结果。
执行+
将是一个可行的替代方案,但是您需要确保结果再次保持在32位范围内。