哈希

参考链接:

https://www.zhihu.com/question/20820286

https://www.liaoxuefeng.com/wiki/1252599548343744/1304227729113121

哈希算法(Hash),又称摘要算法(Disgest)、散列函数,它的作用是:对任意长度输入数据进行计算,得到一个固定长度的结果。

其主要特点:

  • 相同输入得到的输出结果一定相同;
  • 不同输入得到的输出结果大概率不相同。

哈希算法常用于验证原始数据是否被篡改。

常用哈希算法

算法输出长度(位)输出长度(字节)
MD5128 bits16 bytes
SHA-1160 bits20 bytes
RipeMD-160160 bits20 bytes
SHA-256256 bits32 bytes
SHA-512512 bits64 bytes
  • MD5 即 Message-Digest Algorithm 5(信息-摘要算法5, 王小云教授提出),是计算机广泛使用的杂凑算法之一,主流编程语言普遍已有 MD5 实现。

MD5 是输入不定长度信息,经过程序流程,生成4个32位数据,最后联合起来得到一个固定长度为128-bits 散列。

基本方式为,求余、取余、调整长度、与链接变量进行循环运算,得出结果。

MD5 计算广泛应用于错误检查。在一些 BitTorrent 下载中,软件通过计算 MD5 来检验下载到的碎片的完整性。

  • SHA-1(英语:Secure Hash Algorithm 1,中文名:安全散列算法1)是一种密码散列函数,SHA-1可以生成一个被称为消息摘要的160位(20字节)散列值,散列值通常的呈现形式为40个十六进制数。

SHA-1 曾经在许多安全协议中广为使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被视为是MD5的后继者。

 

哈希碰撞(哈希冲突)

哈希算法的输出的字节长度是固定的,而输入的数据长度是不固定的,有无数种可能。所以,哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。

碰撞概率的高低关系到哈希算法的安全性,一个安全的哈希算法必须满足:

  • 碰撞概率低;
  • 不能猜测输出。

通常,哈希算法的输出长度越长,越难产生碰撞,越安全。

 

解决哈希冲突的方法

  • 开放寻址法(open addressing)
  • 链表法(chaining)

开放寻址法

定义:将散列函数扩展定义成探查序列,即每个关键字有一个探查序列h(k,0)、h(k,1)、…、h(k,m-1),这个探查序列一定是0….m-1的一个排列(一定要包含散列表全部的下标,不然可能会发生虽然散列表没满,但是元素不能插入的情况),如果给定一个关键字k,首先会看h(k,0)是否为空,如果为空,则插入;如果不为空,则看h(k,1)是否为空,以此类推。

开放寻址法是一种解决碰撞的方法,对于开放寻址冲突解决方法,比较经典的有线性探测方法(Linear Probing)、二次探测(Quadratic probing)和 双重散列(Double hashing)等方法。

线性探测

当我们往散列表中插入数据时,如果某个数据经过散列函数散列之后,存储位置已经被占用了,我们就从当前位置开始,依次往后查找,看是否有空闲位置,直到找到为止。线性探测法一个很大的弊端就是当散列表中插入的数据越来越多时,散列冲突发生的可能性就会越来越大,空闲位置会越来越少,线性探测的时间就会越来越久。极端情况下,需要从头到尾探测整个散列表,所以最坏情况下的时间复杂度为 O(n)。

二次探测方法

二次探测进行探测的步长变成了原来的“二次方”,它探测的下标序列为 hash(key)+0hash(key)+1^2[hash(key)-1^2]hash(key)+2^2[hash(key)-2^2]

双重散列方法

所谓双重散列,指使用一组散列函数 hash1(key)hash2(key)hash3(key)......先用第一个散列函数,如果计算得到的存储位置已经被占用,再用第二个散列函数,依次类推,直到找到空闲的存储位置。

加载因子(load factor)

不论哪种探测方法,当散列表中空闲位置不多的时候,散列冲突的概率就会大大提高。为了尽可能保证散列表的操作效率,需要尽可能保证散列表中有一定比例的空闲槽位。

加载因子是表示 Hsah 表中元素的填满的程度,加载因子越大,填满的元素越多。这样空间利用率高了,但冲突的机会加大了。反之,加载因子越小,填满的元素越少,冲突的机会减小,但空间浪费多。

链表法

链表法是一种更加常用的散列冲突解决办法。在散列表中,每个位置对应一条链表,所有散列值相同的元素都放到相同位置对应的链表中。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值