Java中字符串的哈希

Java中字符串的哈希,java,hash,byte,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,

我的问题是关于代码,它为字符串生成哈希值,一次求和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);
嗯,我能理解整个代码,除了这两行

1) 为什么我们需要变量“mult”?这可能是散列的乘法方法吗

2) 为什么每次迭代都要将“mult”精确乘以256?在这种情况下,256是多少


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

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

因此,最后我们只接收到一个数字,它是我们之前的
字符
s的逐位串联(例如
10000001 10000010 10000011 10000100


我希望这会有所帮助。

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

因此,最后我们只接收到一个数字,它是我们之前的
字符
s的逐位串联(例如
10000001 10000010 10000011 10000100


我希望这会有所帮助。

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

因此,它所做的是:

  • 它将第一个字符的位保持在最低的8位(第一个字节)
  • 下一个字符的8位位于下8个位置(下一个字节),以此类推,最多4位
我将给出一个4位系统的示例(在这种情况下,我们将乘以16):

它构建
long
和,其位如下所示:

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

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

因此,它所做的是:

  • 它将第一个字符的位保持在最低的8位(第一个字节)
  • 下一个字符的8位位于下8个位置(下一个字节),以此类推,最多4位
我将给出一个4位系统的示例(在这种情况下,我们将乘以16):

它构建
long
和,其位如下所示:

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

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

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

非常感谢您的精彩解释!我终于明白了。但我还有一个问题。如果我们使用无符号int而不是char,那么我们需要乘以65536,对吗?如果是在java中,那么您需要4294967294(java int是32位),但是java没有无符号int。使用
1总是更好是的,你是对的,我错了,写了大约16位(例如输入short)。但是这个想法是正确的,是吗?所以我们乘以65536,然后我们转移到下一个位置。这完全取决于C++中的类型(8, 16, 32或64位)的大小。我终于明白了。但我还有一个问题。如果我们使用无符号int而不是char,那么我们需要乘以65536,对吗?如果是在java中,那么您需要4294967294(java int是32位),但是java没有无符号int。使用
1总是更好是的,你是对的,我错了,写了大约16位(例如输入short)。但是这个想法是正确的,是吗?所以我们乘以65536,然后转移到下一个位置。这取决于C++中的类型(8, 16, 32或64位)的大小,对于无符号的int - yESNO问题!如果您喜欢,请接受,并毫不犹豫地要求更多!好吧我想我可以接受几个答案,但我只能选择一个。这是第一个出现在这里的,对不起。不过还是再次谢谢你,没问题!如果您喜欢,请接受,并毫不犹豫地要求更多!好吧我想我可以接受seve
0110 0010 1001 1101
c[3] c[2] c[1] c[0]