博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法6-4:哈希表现状
阅读量:6218 次
发布时间:2019-06-21

本文共 1086 字,大约阅读时间需要 3 分钟。

战争故事

非常久非常久以前,以前发生过非常多关于哈希函数的战争故事。

那些战争的基本原理就是通过精心构造造成大量的哈希冲突从而占用大量的CPU资源。

被攻击的软件例有下面样例:

  • 带有漏洞的server:攻击者精心构造哈系冲突。仅仅须要56K的网速就能让server死机,从而达到DOS攻击的目的。

  • Perl 5.8.0:攻击者精心构造哈系冲突插入到关联数组中

  • Linux 2.4.20 内核:攻击者精心构造文件名称,造成大量哈系冲突从而让系统性能骤降。

攻击原理

在Java中的String对象非常easy构造哈系冲突。下图展示了Java中哈系冲突的样例。

解决的方法

使用更加高级的哈系函数。避免冲突。比方md4 md5 sha0 sha1 sha2 whirlpool ripemd160。可是md4 md5 sha0 sha1眼下可以找到缺陷,关于MD5的冲突请戳这里:

p=6

MD5不适合用于关联数组,由于开销太大。

两种办法的比較

眼下介绍了两种解决冲突的办法,各自是独立链表和线性探针。

独立链表:

  • 删除元素很方便

  • 随着数据量的添加。性能下降缓慢

  • 哈系冲突对系统的影响小

线性探针:

  • 使用更少的内存。由于没有链表

  • 更好的缓存性能

哈希函数的改进

眼下已经实现了非常多不同的哈希算法。

双值哈希:

一个哈希函数返回两个哈希值,插入元素时插入到较短的链条上。

这样的方法可以降低链条长度的期望值。

双重哈希:

使用线性探针方法,可是每次冲突之后跳过不同数量的元素来寻找空位。

这样的方法可以非常好地消除连续的占位。使得哈希表可以被差点儿填满,可是删除非常难实现。

Cuckoo哈希:

先产生一个哈希,计算出一个位置,假设有冲突。再添加一些參数继续哈希,计算出另外一个位置。直到找到空位位置。这样的方法的查找操作在最坏情况下复杂度是N。

哈系表和二叉树的比較

哈希表和平衡树都能够实现关联数组。

哈希表:

  • 代码简单

  • 这样的方法的性能最好

  • 对于简单的keyword来说这样的方法更快

  • 在java中有更好的系统支持,比方String中使用了hashCode的缓存

二叉树:

  • 更好的性能保障

  • 支持顺序操作(获取某个元素的名次、第N大的值、X到Y的元素数量等)

  • compareTo函数比hashCode函数更easy实现,不easy出错

Java库中对于这两种方法都有实现。

java.util.TreeMap  java.util.TreeSet是通过红黑树实现的,java.util.HashMap  java.util.IdentityHashMap是通过哈希表实现的。

 

你可能感兴趣的文章
老生常谈分布式锁
查看>>
pandas.DataFrame.pivot
查看>>
jmeter设置json断言
查看>>
mac 下安装java环境心得
查看>>
apt-get &dpkg
查看>>
Codeforces 877D Olya and Energy Drinks(BFS+剪枝)
查看>>
R语言绘图(FZ)
查看>>
linux追加所有文件到新的文件(cat)
查看>>
mint-ui之picker爬坑记
查看>>
IT的开始之路——微信小程序(1)
查看>>
以软件周期来说明不同的测试的使用情况
查看>>
Java并发编程:同步容器
查看>>
html style的width不起作用
查看>>
asp.net core系列 47 Identity 自定义用户数据
查看>>
浅析C#代理
查看>>
iOS 关于远程推送(push) 的几个问题
查看>>
Light Life 小组Alfha冲刺(第二天)
查看>>
Miller_Rabin (米勒-拉宾) 素性测试
查看>>
【转载】比较排序算法
查看>>
DBUtils
查看>>