【发布时间】:2021-12-31 05:36:41
【问题描述】:
我的目标是用几个字符串(大约 10000 或更多)来攻击 Java 的 HashMap,它们会产生相同的哈希值。我使用了link 上可用的脚本,将其翻译成 Python3(这样我就可以在我的终端上生成字符串)并在我的机器上运行以生成大约 177147 个字符串。当调用 String.hashCode() 方法时,所有这些字符串都会产生相同的哈希值。从link 可以看出,如果对 HashMap 进行随机读写,时间复杂度将是 O(N*N)。如果 N 很大,则需要更多时间(在这种情况下,N 大于 10000)。但令人惊讶的是,它运行时间不到 2 秒。我希望它需要超过 10 秒。以下是我正在使用的脚本。
# Python3 script to generate strings that produce
# same hash with Java's String.hashCode() method
def combs(n,arr,str,arr_rtn):
if n==1:
for j in range(3):
arr_rtn[str + arr[j]] = 0
else:
for j in range(3):
combs(n-1,arr,str+arr[j],arr_rtn)
arr_src = ['at','bU','c6']
str_tmp = ''
arr_rtn = dict()
t = combs(11,arr_src,str_tmp,arr_rtn)
keys = list(arr_rtn.keys())
print(len(keys))
print(*keys, sep = '\n')
// Java code to insert the generated
// strings into HashMap
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
HashMap<String, Integer> map = new HashMap<>();
for (int i = 0; i < n; i++) {
String s = sc.next();
map.put(s, s.hashCode());
// Should take more time since all strings
// hash to same value
}
System.out.println(map.size());
sc.close();
}
}
我唯一的目标是用产生相同哈希的字符串攻击 HashMap,这样它就需要 20 多秒(至少)来执行。
【问题讨论】:
-
在较慢的计算机上运行?禁用 JIT?在
compareTo方法中使用sleeps 的特殊键类(或者您必须使用String?)?换句话说,20 秒是任意的。表明您已经到达由于碰撞而导致插入速度变慢的点,而不是达到一些随机持续时间不是更好吗? -
请注意,10,000(一万)个元素可能太少了。我刚刚写了一个小测试用例,我用
n元素创建了一个LinkedList,然后搜索一个随机元素n次,每次测试加倍n,它只需要20秒或更长时间n = 2^17. -
另外,复杂性只告诉您执行时间的增长率。执行算法所需的实际时间将取决于计算机。不要试图让算法花费 20 秒,而是考虑证明复杂性是否足够
n^2。您可以通过不断增加问题规模重复测量算法并分析实验时间增长来做到这一点。