如何手动计算字符串的哈希码?

时间:2010-09-25 20:14:45

标签: java hash

我想知道如何手动计算给定字符串的哈希码。我知道在Java中,你可以做类似的事情:

String me = "What you say what you say what?";  
long whatever = me.hashCode();

这都是好事和花花公子,但我想知道如何手工完成。我知道计算字符串哈希码的给定公式如下:

S0 X 31 ^ (n-1) + S1 X 31 ^ (n-2) + .... + S(n-2) X 31 + S(n-1)  

其中S表示字符串中的字符,n表示字符串的长度。然后使用16位unicode,字符串me中的第一个字符将被计算为:

87 X (31 ^ 34)

然而,这造成了一个非常大的数字。我无法想象像这样将所有角色加在一起。那么,为了计算最低阶32位的结果,我该怎么办?很长一段时间等于-957986661,我不知道如何计算?

3 个答案:

答案 0 :(得分:14)

查看java.lang.String的源代码。

/**
 * Returns a hash code for this string. The hash code for a
 * <code>String</code> object is computed as
 * <blockquote><pre>
 * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
 * </pre></blockquote>
 * using <code>int</code> arithmetic, where <code>s[i]</code> is the
 * <i>i</i>th character of the string, <code>n</code> is the length of
 * the string, and <code>^</code> indicates exponentiation.
 * (The hash value of the empty string is zero.)
 *
 * @return  a hash code value for this object.
 */
public int hashCode() {
    int h = hash;
    int len = count;
    if (h == 0 && len > 0) {
        int off = offset;
        char val[] = value;
        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }
        hash = h;
    }
    return h;
}

答案 1 :(得分:6)

此类大多数哈希函数计算哈希值modulo一些大数(例如大素数)。这样可以避免溢出,并将函数返回的值范围保持在指定范围内。但这也意味着无限范围的输入值将从有限的一组可能值(即[0,模数))中获得哈希值,因此存在哈希冲突的问题。

在这种情况下,代码看起来像这样:

   public int hash(String x){
        int hashcode=0;
        int MOD=10007;
        int shift=29;
        for(int i=0;i<x.length();i++){
            hashcode=((shift*hashcode)%MOD+x.charAt(i))%MOD;
        }
        return hashcode; 
    }

为读者练习:

请参阅java.util.String的hashCode函数的代码。你能明白为什么它没有明确使用模数吗?

答案 2 :(得分:1)

以下语句将找到字符串hashCode

String str="Hi";

int a = str.hashCode();//returns 2337

让我们检查一下它的计算准确度

HashCode = s [0] * 31(n-1)+ s [1] * 31(n-2)+ .. s(n-2)

众所周知,位置0的字符是H,位置1的字符是i,字符串长度是2。

==> H * 31(2-1)+ i * 31(2-2)

众所周知,H的ASCII码为72,i为105。

==> 72 * 31 + 105 * 1(任何幂0为1)

==> 2232 + 105 = 2337

来源:https://www.tutorialgateway.org/find-string-hashcode-in-java/