【问题标题】:Why 5 bit left shift in hashing function?为什么哈希函数左移 5 位?
【发布时间】:2019-01-28 07:54:56
【问题描述】:

Simple (non-secure) hash function for JavaScript?Generate a Hash from string in Javascript 中给出了在 JS 中生成散列函数的流行答案

代码的一个例子是:

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;
}

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

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

【问题讨论】:

  • 很确定没关系 - 这只是将字符串转换为哈希的一种方法的示例。您可以使用您喜欢的任何算法,使用您喜欢的任何移位、加法、减法等。

标签: javascript hash bitwise-operators


【解决方案1】:

(hash &lt;&lt; 5)(hash * 32),所以 ((hash &lt;&lt; 5) - hash)(hash * 31)。问题的答案中描述了乘以 31 的原因 Why does Java's hashCode() in String use 31 as a multiplier?

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

【讨论】:

  • 另一个帮助我理解的答案是crypto.stackexchange.com/a/8534。特别是,位移被如此广泛地使用是因为它们促进了良好的扩散。
  • 是的,乘以 31 基本上是两个位移位(乘以 5 和乘以 1)和减法。甚至认为,像 Murmur 这样的其他哈希算法具有更好的扩散/混淆/雪崩效应。
猜你喜欢
  • 2021-01-07
  • 1970-01-01
  • 2015-04-29
  • 2018-10-13
  • 2018-05-12
  • 1970-01-01
  • 2012-02-26
  • 2015-04-12
  • 2010-09-07
相关资源
最近更新 更多