这是查找和打印任何所需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
和一个大的英语单词列表来表示firstParts
and lastParts
,我们可以找到众所周知的pollinating sandboxes
as revolvingly admissable
、laccaic dephase
、toxity fizzes
等。
请注意,如果您为 和 提供一个大小为NfindStrings
的大型列表,并为 提供一个简短的固定列表,它会在O(N)时间内运行。firstParts
lastParts
midParts