【问题标题】:Use of << and >>> in a hash function在散列函数中使用 << 和 >>>
【发布时间】:2016-09-15 16:58:21
【问题描述】:

我有一个 C 语言项目,我需要为 void 指针创建一个合适的哈希函数,该指针可能包含字母数字字符、整数或只是普通的 ol' 字符。

我需要使用多项式哈希函数,而不是乘以常数,我应该使用部分和的循环移位固定位数。 在这个页面here ,有java代码(我假设这是java,因为使用了字符串):

static int hashCode(String s) {
  int h = 0;
  for (int i = 0; i < s.length(); i++) {
    h = (h << 5) | (h >>> 27); // 5-bit cyclic shift of the running sum
    h += (int) s.charAt(i); // add in next character
  }
  return h;
}

下面的这条线到底在做什么?

h = (h << 5) | (h >>> 27); // 5-bit cyclic shift of the running sum

是的,评论说 5 位循环移位,但 &lt;&lt;|&gt;&gt;&gt; 操作数在这方面如何工作?我以前从未见过或使用过它们。

【问题讨论】:

  • 您进行了哪些研究来尝试了解这些运营商*的工作方式?
  • (h &gt;&gt;&gt; 27)你确定吗?
  • @AlterMann 你为什么要问,它似乎完全合法?总而言之,它是 ROTL 5。
  • @MarkoTopolnik,在 C 中无效,这就是我问的原因
  • @AlterMann 直接来自链接页面。

标签: java c hash hashcode


【解决方案1】:

正如它所说,这是一个 5 位循环左移。这意味着所有位都向左移动,“移出”的位被添加到右侧,五次。

代码将h 的值替换为两个位模式的值 OR 一起。第一个位模式是原始值左移 5 位。第二个值是原始值右移 27 位。

5 位左移将除最左边 5 位之外的所有位置于其最终位置。最左边的 5 位被该移位“移出”,并用零替换为输出的最右边位。 27 位的右移将最左边的 5 位作为最右边的位放在它们的最终位置,最左边的 27 位移入零。将它们组合在一起会产生所需的输出。

&gt;&gt;&gt; 是 Java 的 unsigned 移位操作。在 C 或 C++ 中,您只需使用 &gt;&gt;

【讨论】:

  • h &gt;&gt;&gt; 27 似乎没有改变值,错字?
  • @AlterMann &gt;&gt;&gt; 是 Java 中的“零填充右移”运算符。
  • 不,这不是错字。 &gt;&gt;&gt; 是“常规”右移,&gt;&gt; 是符号扩展右移,在这里你绝对不想要。
  • @Monkleys 这不是关于素数,而是关于将 ROTL 实现为两个班次。 5 + 27 是 32,而 7 + 13 不是。通常,哈希实现中最关键的一点是尽可能多地保留信息。 ROTL 可以完美地保存信息,而您的任意班次组合则不能。
  • @Monkleys 因为这不是循环移位,所以会有很大的不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-29
  • 1970-01-01
  • 2012-09-09
  • 2021-07-14
  • 2013-07-12
相关资源
最近更新 更多