这是查找和打印任何所需hashCode值的字符串的代码:
public static int findIntInverse(int x) {
// find the number y such that as an int (after overflow) x*y = 1
// assumes x is odd, because without that it isn't possible.
// works by computing x ** ((2 ** 32) - 1)
int retval = 1;
for (int i = 0; i < 31; i++) {
retval *= retval;
retval *= x;
}
return retval;
}
public static void findStrings(
int targetHash,
Iterable<String> firstParts,
Iterable<String> midParts,
Iterable<String> lastParts) {
Map<Integer, String> firstHashes = new HashMap<>();
for (String firstPart : firstParts) {
firstHashes.put(firstPart.hashCode(), firstPart);
}
int maxlastlen = 0;
int maxmidlen = 0;
for (String midPart : midParts) {
maxmidlen = Math.max(midPart.length(), maxmidlen);
}
for (String lastPart : lastParts) {
maxlastlen = Math.max(lastPart.length(), maxlastlen);
}
List<Integer> hashmuls = new ArrayList<>();
String baseStr = "\u0001";
for (int i = 0; i <= maxmidlen + maxlastlen; i++) {
hashmuls.add(baseStr.hashCode());
baseStr += "\0";
}
// now change each hashmuls into its negative "reciprocal"
for (int i = 0; i < hashmuls.size(); i++) {
hashmuls.set(i, -findIntInverse(hashmuls.get(i)));
}
for (String lastPart : lastParts) {
for (String midPart : midParts) {
String tail = midPart + lastPart;
Integer target = hashmuls.get(tail.length()) * (tail.hashCode() - targetHash);
if (firstHashes.containsKey(target)) {
System.out.print(firstHashes.get(target));
System.out.println(tail);
}
}
}
}
通过使用常用英语单词列表作为每个部分的种子,发现了一些有趣的发现:
sand nearby chair
king concentration feeling
childhood dish tight
war defensive to
ear account virus
使用Arrays.asList(" ")asmidParts和一个大的英语单词列表来表示firstPartsand lastParts,我们可以找到众所周知的pollinating sandboxesas revolvingly admissable、laccaic dephase、toxity fizzes等。
请注意,如果您为 和 提供一个大小为NfindStrings的大型列表,并为 提供一个简短的固定列表,它会在O(N)时间内运行。firstPartslastPartsmidParts