返回此字符串的哈希码。 String 对象的哈希码计算为
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用 int 算法,其中 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。 (空字符串的散列值为零。)
现在你只需要解决-2147483648(可能只限制可打印的 ASCII 字符:32-127):)
或者你蛮力(这需要一段时间):
public class HashFinder {
private static final int SIZE = 7;
private static long hashesCalculated = 0L;
public static void main(String[] args) {
hashesCalculated = 0L;
final long start = System.nanoTime();
findHash(SIZE);
final long duration = System.nanoTime() - start;
System.err.println("Checked strings of size " + SIZE);
System.err.println(hashesCalculated + " hashes in " + TimeUnit.NANOSECONDS.toSeconds(duration) + "s");
}
public static void findHash(final int size) {
findHash("", size);
}
public static void findHash(final String prefix, final int size) {
if (size <= 0) {
return;
}
final StringBuilder sb = new StringBuilder(prefix).append(' ');
for (char c = ' '; c < '~'; ++c) {
sb.setCharAt(prefix.length(), c);
final String s = sb.toString();
++hashesCalculated;
if (s.hashCode() == Integer.MIN_VALUE) {
System.out.printf("Found string with min hashCode! '%s'%n", s);
}
findHash(s, size - 1);
}
}
}
但是分配所有这些字符串和字符串构建器是昂贵的。当我们从 char 数组手动计算哈希码时,暴力破解变得可行:
public class HashFinderBytes {
public static void main(String[] args) {
final char start = ' ', end = '~';
for (int size = 1; size <= 9; size++) {
char[] chars = new char[size];
Arrays.fill(chars, start);
final long startNano = System.nanoTime();
final long combinations = BigInteger.valueOf(end - start).pow(size).longValue();
System.err.println("Checking " + combinations + " strings of size " + size);
for (long i = 0; i < combinations; ++i) {
if (hashCode(chars) == Integer.MIN_VALUE) {
System.out.printf("Found string with min hashCode! "%s"%n", new String(chars));
System.out.println("Sanity check: " + (new String(chars).hashCode() == Integer.MIN_VALUE));
}
for (int j = 0; j < chars.length; ++j) {
++chars[j];
if (chars[j] <= end) {
break;
}
chars[j] = (byte) start;
}
}
final long duration = System.nanoTime() - startNano;
final long millis = TimeUnit.NANOSECONDS.toMillis(duration);
System.err.println("in " + millis + "ms (" + (combinations / millis) + " ops/ms)");
}
}
public static int hashCode(char[] value) {
int h = 0;
for (char v : value) {
h = 31 * h + (v & 0xff);
}
return h;
}
}
事实上,有很多字符串的哈希码与Integer.MIN_VALUE 相同。
长度 6:
I='<*!
H'<*!
G{'<*!
I<F<*!
H[F<*!
GzF<*!
I;e<*!
HZe<*!
Gye<*!
I=&[*!
H&[*!
G{&[*!
I<E[*!
H[E[*!
GzE[*!
I;d[*!
HZd[*!
Gyd[*!
I=%z*!
H%z*!
G{%z*!
I<Dz*!
H[Dz*!
GzDz*!
I;cz*!
HZcz*!
Gycz*!
I=';I!
H';I!
G{';I!
I<F;I!
H[F;I!
GzF;I!
I;e;I!
HZe;I!
Gye;I!
I=&ZI!
H&ZI!
G{&ZI!
I<EZI!
H[EZI!
GzEZI!
I;dZI!
HZdZI!
GydZI!
I=%yI!
H%yI!
G{%yI!
I<DyI!
H[DyI!
GzDyI!
I;cyI!
HZcyI!
GycyI!
I=':h!
H':h!
G{':h!
I<F:h!
H[F:h!
GzF:h!
I;e:h!
HZe:h!
Gye:h!
I=&Yh!
H&Yh!
G{&Yh!
I<EYh!
H[EYh!
GzEYh!
I;dYh!
HZdYh!
GydYh!
I=%xh!
H%xh!
G{%xh!
I<Dxh!
H[Dxh!
GzDxh!
I;cxh!
HZcxh!
Gycxh!
长度 7(以下所有字符串均以空格字符结尾);未全部显示:
p4*|{e
oS*|{e
nr*|{e
p3I|{e
oRI|{e
nqI|{e
p2h|{e
oQh|{e
nph|{e