在Java中散列字符串

时间:2013-06-23 11:07:38

标签: java hash byte

我的问题是关于代码,它产生字符串的哈希值,一次总计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值都转换为long整数类型,在for循环的每次迭代中对结果求和。我在上面提到的这两行可疑代码如下:

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

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

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

2)为什么我们在每次迭代时将'mult'精确乘以256?在这种情况下256是什么?

如果你们中的一些人已经面对这个代码,或者你知道这些代码中执行的想法,请帮助我理解它:)

3 个答案:

答案 0 :(得分:1)

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

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

我希望这会有所帮助。

答案 1 :(得分:0)

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

所以,它的作用是:

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

我将举一个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] 

答案 2 :(得分:0)

代码基本上一次只有一个byte。每个字节是8位,或数字256.换句话说,乘以256就像将值向左移一个字节。