Hash算法及常见碰撞解决方法

Posted 程序员小圈圈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hash算法及常见碰撞解决方法相关的知识,希望对你有一定的参考价值。


转载请标明出处^_^
原文首发于:https://www.zhangruibin.com
本文出自于:RebornChang的博客

Hash算法及常见碰撞解决方法

Hash算法及由来

Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

  通过将单向数学函数(有时称为“哈希算法”)应用到任意数量的数据所得到的固定大小的结果。如果输入数据中有变化,则哈希也会发生变化。哈希可用于许多操作,包括身份验证和数字签名。也称为“消息摘要”。

  简单解释:哈希(Hash)算法,即散列函数。它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出。哈希函数的这种单向特征和输出数据长度固定的特征使得它可以生成消息或者数据。---以上摘自网络

Hash算法用途

1.数据校验

上面说到的md5就是其中的一个, 好像还有一个什么SHA, 不过我不知道, 也就不展开探讨了.

md5可以将一个文件经过计算转换成一个指定长度的字符串, 可以防止文件被篡改, 但是通过加密后的字符串很难逆向推出原文.

前面那个例子可以看到, 即使文件被修改了一点点, 也会导致计算后的值发生很大变换.

2.唯一标识

比如说, 现在有十万个文件, 给你一个文件, 要你在这十万个文件中查找是否存在. 一个很笨的办法就是把每一文件都拿出来, 然后按照二进制串一一进行对比. 但是这个操作注定是比较费时的.

可以用哈希算法对文件进行计算, 然后比较哈希值是否相同. 因为存在哈希冲突的情况, 你可以在相同哈希值的文件再进行二进制串比较.

3.哈希表

在哈希表中使用哈希函数已经并不陌生了, 不再赘述.

4.负载均衡

比如说, 现在又多台服务器, 来了一个请求, 如何确定这个请求应该路由到哪个路由器呢?当然, 必须确保相同的请求经过路由到达同一个服务器. 一种办法就是保存一张路由关系的表, 比如客户端IP和服务器编号的映射, 但是如果客户端很多, 势必查找的时间会很长. 这时, 可以将客户端的唯一标识信息(如:IP、username等)进行哈希计算, 然后与服务器个数取模, 得到的就是服务器的编号.

5.分布式存储

当我们有大量数据时, 一般会选择将数据存储到多个服务器, 为了提高读取与写入的速度嘛. 决定将文件存储到哪台服务器, 就可以通过哈希算法取模的操作来得到.

原文链接

一致性Hash算法

什么是一致性hash算法

简单的说:为了减少碰撞,按照一定的物理规律模拟出来一个环,将自己的有限资源分布在环上,然后每当一个请求寻址过来时,按照计算给予分配环上的资源。以上这句话是本人自己总结的,里面有几个问题:1.环的构造方式是什么?2.怎样将有限的资源在环上分配?3.怎样合理有效的分配资源?4.怎样判断构造的环的优缺?... 可以参考本连接。

Hash碰撞及避免碰撞策略

Hash碰撞

对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰撞冲突。如下将介绍如何处理冲突,当然其前提是一致性hash。

避免Hash碰撞策略

1.开放地址法(再散列法)

开放地执法有一个公式:Hi=(H(key)+di) MOD m i=1,2,…,k(k<=m-1) 其中,m为哈希表的表长。di 是产生冲突的时候的增量序列。如果di值可能为1,2,3,…m-1,称线性探测再散列。如果di取1,则每次冲突之后,向后移动1个位置.如果di取值可能为1,-1,2,-2,4,-4,9,-9,16,-16,…kk,-kk(k<=m/2),称二次探测再散列。如果di取值可能为伪随机数列。称伪随机探测再散列。

2.再哈希法Rehash

3.链地址法(拉链法)

拉链法的优缺点

优点:
缺点:

指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。

4.建立一个公共溢出区

假设哈希函数的值域为[0,m-1],则设向量HashTable[0..m-1]为基本表,另外设立存储空间向量OverTable[0..v]用以存储发生冲突的记录。以上部分参考自

注:本文为整理学习记录所用,博主不产生这种知识,只是知识的搬运工。如有侵权请告知,秒删!



以上是关于Hash算法及常见碰撞解决方法的主要内容,如果未能解决你的问题,请参考以下文章

hashmap会问到数组索引,hash碰撞怎么解决

Java面试题之hashmap中用什么hash算法解决碰撞的?

[译]C语言实现一个简易的Hash table

hash冲突随笔

Unity3D使用时发现的问题及解决方法(触发碰撞条件)

CTF常见RSA相关问题的解决(复现)