1

我的问题是关于代码,它为字符串生成哈希值,一次求和 4 个字节。它完全有效,但我无法理解这段代码的某些行,即在某些行中执行的想法。因此,我需要一些非常熟悉散列的人的帮助。

好吧,这是完整的代码:

long sfold(String s, int M) {
 int intLength = s.length() / 4;
 long sum = 0;
 for (int j = 0; j < intLength; j++) {
   char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
   long mult = 1;
   for (int k = 0; k < c.length; k++) {
 sum += c[k] * mult;
 mult *= 256;
   }
 }

 char c[] = s.substring(intLength * 4).toCharArray();
 long mult = 1;
 for (int k = 0; k < c.length; k++) {
   sum += c[k] * mult;
   mult *= 256;
 }

 return(Math.abs(sum) % M);

}

这里每个 char 值都转换为长整数类型,对 for 循环的每次迭代的结果求和。我上面提到的这两行可疑的代码如下:

sum += c[k] * mult;
mult *= 256;

好吧,我可以理解整个代码,除了这两行......

1)为什么我们需要变量'mult'?它可能是使用乘法方法进行散列吗?

2) 为什么我们在每次迭代中将“mult”乘以 256?在这种情况下,256 是什么?

如果你们中的一些人遇到过这段代码,或者你知道在这些行中执行的想法,请帮助我理解它:)

4

3 回答 3

1

由于它是 char 的事实,c[k]它的大小为 8 位,而 8 位正好是 256 个可能的数字。因此,例如,我们有char[] c = new char[]{'a, 'b', 'c', 'd'}, 在这里'a'有点明智的形式看起来像10000001和类似的b东西10000010等等。现在的问题是我们如何形成sum,首先我们只是a按位取我们的表示,所以sum成为10000001,接下来我们取b按位形式并将其乘以实际上只是向左 8 位的按位移位256,这意味着'b' * 25610000001 * 100000000 = 1000000100000000(位形式的 256 为 100000000)相同,现在当我们将其'b' * 256与先前的总和相加时,这意味着只需用a位形式替换最后 8 位。接下来会发生同样的事情。

所以最后我们只收到一个数字,它是我们之前的 s 的按位连接char(例如10000001 10000010 10000011 10000100)。

我希望这会有所帮助。

于 2013-06-23T11:31:13.617 回答
0

乘以256实际上是将位向左移动 8 个位置(1 个字节)。

所以,它的作用是:

  • 它将第一个字符的位保持在最低 8 位(第一个字节)中,
  • 下一个字符的 8 位在接下来的 8 个位置(下一个字节),依此类推,最多四个。

我将举一个 4 位系统的示例(在这种情况下,我们将乘以 16):

c[0] = 1101
c[1] = 1001 
c[2] = 0010 
c[3] = 0110

它构建long总和,其位如下:

0110 0010 1001 1101
c[3] c[2] c[1] c[0] 
于 2013-06-23T11:32:13.350 回答
0

代码基本上一次byte一个。每个字节为 8 位,即数字 256。换句话说,乘以 256 就像将值向左移动一个字节。

于 2013-06-23T11:32:33.633 回答