哈希冲突和哈希冲突攻击解析

一、什么是哈希冲突?

当数据插入到哈希表时,不同key值产生的h(key)却是相等的,这个时候就产生了冲突。

二、怎么解决哈希冲突?

常用的几种方法有:开放定址法、拉链法、再哈希法、建立公共溢出区。

1、开放定址法

所谓的开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入 
公式为:fi(key) = (f(key)+di) MOD m (di=1,2,3,……,m-1)


详解:当冲突发生时,使用某种探测技术在散列表中形成一个探测序列(根据生成序列的规则不同,可以有线性探查法、伪随机探查法、二次探查法、双散列法等)。沿此序列逐个单元地查找,直到找到给定的关键字,或者碰到一个开放的地址(即该地址单元为空)为止。


比如说(借用例子),我们的关键字集合为{12,67,56,16,25,37,22,29,15,47,48,34},表长为12。 我们用散列函数f(key) = key mod l2 
当计算前S个数{12,67,56,16,25}时,都是没有冲突的散列地址,直接存入: 

这里写图片描述 
计算key = 37时,发现f(37) = 1,此时就与25所在的位置冲突。 
于是我们应用上面的公式f(37) = (f(37)+1) mod 12 = 2。于是将37存入下标为2的位置: 
这里写图片描述

2、拉链法

拉链法是解决哈希冲突的一种行之有效的方法(比如php、java就是使用该方法解决哈希冲突),某些哈希地址可以被多个关键字值共享,这样可以针对每个哈希地址建立一个单链表。

原理:每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表连接起来。

如(借用例子): 键值对k2, v2与键值对k1, v1通过计算后的索引值都为2,这时及产生冲突,但是可以通道next指针将k2, k1所在的节点连接起来,这样就解决了哈希的冲突问题 
这里写图片描述

扫描二维码关注公众号,回复: 16791509 查看本文章

3、再哈希法

再哈希法理解起来比较简单,再哈希法又叫双哈希法,有多个不同的Hash函数,当发生冲突时,就可以使用第二个函数、如果在发生冲突继续使用第三个函数、以此类推,一直到无冲突为止,再哈希法虽然不容易发生聚集,但是大大增加了计算时间。

4、建立公共溢出区

原理:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。

三、利用哈希冲突来进行攻击

上面我提到,php和java之类的语言用的就是拉链法解决哈希冲突的。

其攻击原理就是:构造恶意的数据使hash表退化为链表,每次插入数据都会遍历链表,消耗大量服务器资源,从而达到攻击目的。

例如:php的数组就是利用hash表实现的,下面用例子看看恶意构造的数据和普通数据的区别

    <?php
    $size = pow(2, 16);
    $startTime = microtime(true);
    $array = array();
    for ($key = 0, $maxKey = ($size - 1) * $size; $key <= $maxKey; $key += $size) {
        $array[$key] = 0;
    }
    $endTime = microtime(true);
    echo '插入 ', $size, ' 个恶意的元素需要 ', $endTime - $startTime, ' 秒', "\n";

    $startTime = microtime(true);
    $array = array();
    for ($key = 0, $maxKey = $size - 1; $key <= $maxKey; ++$key) {
        $array[$key] = 0;
    }
    $endTime = microtime(true);
    echo '插入 ', $size, ' 个普通元素需要 ', $endTime - $startTime, ' 秒', "\n";

上面的例子, 就是恶意构造数据,导致每次数据的写入都产生了哈希冲突,导致每一次存入就会遍历整个链表,在我的机器上的执行结果如下:

(这是我机器配置高一些,还有就是php7优化了hash表的结构和算法,如果用的php5.6,时间会更久)

插入 65536 个恶意的元素需要 7.9304070472717 秒
插入 65536 个普通元素需要 0.0048370361328125 秒

可参考鸟哥博客地址:PHP数组的Hash冲突实例 - 风雪之隅

猜你喜欢

转载自blog.csdn.net/panjiapengfly/article/details/121145250