perl - perl 如何解决哈希中可能的哈希冲突?
问题描述
众所周知,perl 将其“散列”类型实现为具有计算索引的表,其中这些索引是截断的散列。
我们也知道,散列函数可以(并且将根据概率)碰撞,将相同的散列提供给 2 个或更多不同的输入。
然后:当 perl 解释器发现一个键生成的散列值与另一个键相同时,它如何处理?它会处理它吗?
注意:这不是关于哈希算法,而是关于哈希表实现中的冲突解决。
解决方案
Perl 哈希是一个链表数组。
+--------+ +--------+
| -------->| |
+--------+ +--------+
| | | key1 |
+--------+ +--------+
| ------+ | val1 |
+--------+ | +--------+
| | |
+--------+ | +--------+ +--------+
+-->| ------>| |
+--------+ +--------+
| key2 | | key3 |
+--------+ +--------+
| val2 | | val3 |
+--------+ +--------+
散列函数产生一个用作数组索引的值,然后执行关联链表的线性搜索。
这意味着查找的最坏情况是 O(N)。那么为什么人们说它是 O(1) 呢?你可以声称如果你让列表不超过某个恒定长度,这就是 Perl 所做的。它使用两种机制来实现这一点:
- 增加桶的数量。
- 散列算法扰动。
平均而言,将桶数加倍应该将给定的条目数除以一半。例如,
305419896 % 4 = 0 and 943086900 % 4 = 0
305419896 % 8 = 0 and 943086900 % 8 = 4
但是,恶意行为者可以选择不会发生这种情况的值。这就是哈希扰动发挥作用的地方。每个散列都有自己的随机数,它会扰乱(导致变化)散列算法的输出。由于攻击者无法预测随机数,因此他们无法选择会导致冲突的值。需要时,Perl 可以使用新的随机数重建散列,使键映射到与以前不同的存储桶,从而分解长链。
推荐阅读
- amazon-web-services - 为什么以 AWS 根用户身份登录时不允许角色切换?
- tfs - 如何在 android studio 中安装 tfs?
- r - 如何从 casandara 和 S3 读取/写入 sparkR 和 sparklyr 数据帧?
- ansible - 无法将 ansible_user 与本地连接一起使用
- amazon-web-services - 从 CLI 上传 VPC 中的 Lambda 函数时遇到问题
- algorithm - 清理堆的时间复杂度是多少?
- laravel - 具有条件约束的查询范围
- c++ - 使用继承修复大型类
- c++ - C ++ 11访问类内存变量是否具有本地副本
- r - 如何在另一列中查找名称子集?