简体   繁体   English

非空字符串的哈希码是否可以为零?

[英]Can a non-empty string have a hashcode of zero?

By "non-empty", I mean in this question a string which contains at least one non-zero character. 通过“非空”,我的意思是在这个问题中包含至少一个非零字符的字符串。

For reference, here's the hashCode implementation : 作为参考,这是hashCode实现:

1493    public int hashCode() {
1494        int h = hash;
1495        if (h == 0) {
1496            int off = offset;
1497            char val[] = value;
1498            int len = count;
1499
1500            for (int i = 0; i < len; i++) {
1501                h = 31*h + val[off++];
1502            }
1503            hash = h;
1504        }
1505        return h;
1506    }

and the algorithm is specified in the documentation. 并且算法在文档中指定。

Before an integer overflow occurs, the answer is easy: it's no. 在发生整数溢出之前,答案很简单:不是。 But what I'd like to know is if, due to integer overflow, it's possible for a non-empty string to have a hashcode of zero? 但我想知道的是,由于整数溢出,非空字符串的哈希码是否可能为零? Can you construct one? 你能建一个吗?

What I'm looking for would ideally be a mathematical demonstration (or a link to one) or a construction algorithm. 我正在寻找的理想情况是数学演示(或链接到一个)或构造算法。

Sure. 当然。 The string f5a5a608 for example has a hashcode of zero. 例如,字符串f5a5a608的哈希码为零。

I found that through a simple brute force search: 我发现通过一个简单的蛮力搜索:

public static void main(String[] args){
    long i = 0;
    loop: while(true){
        String s = Long.toHexString(i);
        if(s.hashCode() == 0){
            System.out.println("Found: '"+s+"'");
            break loop;
        }
        if(i % 1000000==0){
            System.out.println("checked: "+i);              
        }
        i++;
    }       
}

Edit: Joseph Darcy, who worked on the JVM, even wrote a program that can construct a string with a given hashcode (to test the implementation of Strings in switch/case statements) by basically running the hash algorithm in reverse. 编辑:在JVM上工作的Joseph Darcy甚至编写了一个程序,它可以通过基本上反向运行哈希算法来构造一个带有给定哈希码的字符串 (以测试switch / case语句中字符串的实现)。

just be care of that int h; 只是照顾那个int h; . It may overflow, every string that satisfy h % 2^31 == 0 may lead to this. 它可能溢出,每个满足h % 2^31 == 0字符串都可能导致这种情况。

public class HelloWorld {
    public static void main(String []args) {
       System.out.println("\u0001!qbygvW".hashCode());
        System.out.println("9 $Ql(0".hashCode());
        System.out.println(" #t(}lrl".hashCode());
        System.out.println(" !!#jbw}a".hashCode());
        System.out.println(" !!#jbw|||".hashCode());
        System.out.println(" !!!!Se|aaJ".hashCode());
        System.out.println(" !!!!\"xurlls".hashCode());
    }
}

A lot of strings... 很多字符串......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM