为什么散列函数左移 5 位?

Tom*_*ane 5 javascript hash bitwise-operators

在 JavaScript 的简单(非安全)散列函数中给出了在 JS 中生成散列函数的流行答案在Javascript中从字符串生成哈希

代码示例之一是:

String.prototype.hashCode = function() {
    var hash = 0;
    if (this.length == 0) {
        return hash;
    }
    for (var i = 0; i < this.length; i++) {
        var char = this.charCodeAt(i);
        hash = ((hash<<5)-hash)+char;
        hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
}
Run Code Online (Sandbox Code Playgroud)

对我来说没有意义的一行是 hash = ((hash<<5)-hash)+char;

有人可以解释为什么要这样做吗?我认为我们正在5 bit left shift对哈希进行处理。有什么理由为什么它是 5 位而不是 4 位或 6 位吗?另外为什么我们然后减去散列并添加字符?

Tho*_*ler 5

(hash << 5)(hash * 32)((hash << 5) - hash)也是(hash * 31)。问题的答案中描述了乘以 31 的原因 为什么 Java 的 hashCode() in String 使用 31 作为乘数?

因此,如果将其更改为(hash * 31),则结果相同。可能(hash << 5) - hash稍微快一点,因为移位/减法可能比乘法快。但是,是否真的如此取决于许多因素(是否使用 JIT 编译,以及 JIT 中的优化,甚至处理器)。所以我假设代码的作者对其进行了测试,并发现对于他的情况来说它更快。