导航:首页 > 源码编译 > 处理效率最高的哈希算法是什么

处理效率最高的哈希算法是什么

发布时间:2024-01-06 15:34:01

‘壹’ 哈希加密算法

MD5即Message-Digest Algorithm 5(信息摘要算法5),是计算机广泛使用的散列算法之一。经MD2、MD3和MD4发展而来,诞生于20世纪90年代初。用于确保信息传输完整一致。虽然已被破解,但仍然具有较好的安全性,加之可以免费使用,所以仍广泛运用于数字签名、文件完整性验证以及口令加密等领域。

算法原理:

散列算法得到的结果位数是有限的,比如MD5算法计算出的结果字长为128位,意味着只要我们穷举2^128次,就肯定能得到一组碰撞,下面让我们来看看一个真实的碰撞案例。我们之所以说MD5过时,是因为它在某些时候已经很难表现出散列算法的某些优势——比如在应对文件的微小修改时,散列算法得到的指纹结果应当有显着的不同,而下面的程序说明了MD5并不能实现这一点。

而诸如此类的碰撞案例还有很多,上面只是原始文件相对较小的一个例子。事实上现在我们用智能手机只要数秒就能找到MD5的一个碰撞案例,因此,MD5在数年前就已经不被推荐作为应用中的散列算法方案,取代它的是SHA家族算法,也就是安全散列算法(Secure Hash Algorithm,缩写为SHA)。

SHA实际包括有一系列算法,分别是SHA-1、SHA-224、SHA-256、SHA-384以及SHA-512。而我们所说的SHA2实际是对后面4中的统称。各种SHA算法的数据比较如下表,其中的长度单位均为位:

MD5和SHA1,它们都有4个逻辑函数,而在SHA2的一系列算法中都采用了6个逻辑函数。
以SHA-1为例,算法包括有如下的处理过程:

和MD5处理输入方式相同

经过添加位数处理的明文,其长度正好为512位的整数倍,然后按512位的长度进行分组,可以得到一定数量的明文分组,我们用Y 0 ,Y 1 ,……Y N-1 表示这些明文分组。对于每一个明文分组,都要重复反复的处理,这些与MD5都是相同的。

而对于每个512位的明文分组,SHA1将其再分成16份更小的明文分组,称为子明文分组,每个子明文分组为32位,我们且使用M[t](t= 0, 1,……15)来表示这16个子明文分组。然后需要将这16个子明文分组扩充到80个子明文分组,我们将其记为W[t](t= 0, 1,……79),扩充的具体方法是:当0≤t≤15时,Wt = Mt;当16≤t≤79时,Wt = ( W t-3 ⊕ W t-8 ⊕ W t-14 ⊕ W t-16 ) <<< 1,从而得到80个子明文分组。

所谓初始化缓存就是为链接变量赋初值。前面我们实现MD5算法时,说过由于摘要是128位,以32位为计算单位,所以需要4个链接变量。同样SHA-1采用160位的信息摘要,也以32位为计算长度,就需要5个链接变量。我们记为A、B、C、D、E。其初始赋值分别为:A = 0x67452301、B = 0xEFCDAB89、C = 0x98BADCFE、D = 0x10325476、E = 0xC3D2E1F0。

如果我们对比前面说过的MD5算法就会发现,前4个链接变量的初始值是一样的,因为它们本来就是同源的。

经过前面的准备,接下来就是计算信息摘要了。SHA1有4轮运算,每一轮包括20个步骤,一共80步,最终产生160位的信息摘要,这160位的摘要存放在5个32位的链接变量中。

在SHA1的4论运算中,虽然进行的就具体操作函数不同,但逻辑过程却是一致的。首先,定义5个变量,假设为H0、H1、H2、H3、H4,对其分别进行如下操作:

(A)、将A左移5为与 函数的结果求和,再与对应的子明文分组、E以及计算常数求和后的结果赋予H0。

(B)、将A的值赋予H1。

(C)、将B左移30位,并赋予H2。

(D)、将C的值赋予H3。

(E)、将D的值赋予H4。

(F)、最后将H0、H1、H2、H3、H4的值分别赋予A、B、C、D

这一过程表示如下:

而在4轮80步的计算中使用到的函数和固定常数如下表所示:

经过4轮80步计算后得到的结果,再与各链接变量的初始值求和,就得到了我们最终的信息摘要。而对于有多个明文分组的,则将前面所得到的结果作为初始值进行下一明文分组的计算,最终计算全部的明文分组就得到了最终的结果。

‘贰’ 哈希表、哈希算法、一致性哈希表

    散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。它通过把关键码映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数(哈希函数),存放记录的数组叫做散列表。

  优点:

        哈希表可以提供快速的操作。

缺点:

        哈希表通常是基于数组的,数组创建后难于扩展。

        也没有一种简便的方法可以以任何一种顺序〔例如从小到大)遍历表中的数据项 。

    综上, 如果不需要有序遍历数据,井且可以提前预测数据量的大小。那么哈希表在速度和易用性方面是无与伦比的。

        1. 使用哈希函数将被查找的键转换为数组的索引。

        2. 处理哈希碰撞冲突。

    若关键字为 k ,则其值存放在 f(k) 的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系 f 为散列函数,按这个思想建立的表为散列表。

    若对于关键字集合中的任一个关键字,经散列函数映象到地址集合中任何一个地址的概率是相等的,则称此类散列函数为 均匀散列函数 (Uniform Hash function),这就是使关键字经过散列函数得到一个"随机的地址",从而减少碰撞。

散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位。

一个好的散列函数一般应该考虑下列因素 :

    1.计算简单,以便提高转换速度。

    2.关键词对应的地址空间分布均匀,以尽量减少冲突。

1.   直接寻址法

    取关键字或者关键字的某个线性函数值作为哈希地址,即H(Key)=Key或者H(Key)=a*Key+b(a,b为整数),这种散列函数也叫做自身函数.如果H(Key)的哈希地址上已经有值了,那么就往下一个位置找,直到找到H(Key)的位置没有值了就把元素放进去。

2.   数字分析法

    数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。

3.   平方取中法

    取关键字平方后的中间几位作为散列地址。这种方法的原理是通过取平方扩大差别,平方值的中间几位和这个数的每一位都相关,则对不同的关键字得到的哈希函数值不易产生冲突,由此产生的哈希地址也较为均匀。该方法适用于关键字中的每一位都有某些数字重复出现频度很高的现象。

4.   折叠法

    折叠法是将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(注意:叠加和时去除进位)作为散列地址。

    数位叠加可以有移位叠加和间界叠加两种方法。移位叠加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加。

    该方法适用于关键字特别多的情况。

5.   随机数法

    选择一个随机数,作为散列地址,通常用于关键字长度不同的场合。

6.   除留余数法

    取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址.即H(Key)=Key MOD p,p<=m.不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选得不好,则很容易产生冲突。

    对不同的关键字可能得到同一散列地址,即 k1≠k2 ,而 f(k1)=f(k2) ,这种现象称为碰撞(英语:Collision)。具有相同函数值的关键字对该散列函数来说称做同义词。

    通过构造性能良好的散列函数,可以减少冲突,但一般不可能完全避免冲突,因此解决冲突是哈希法的另一个关键问题。 创建哈希表和查找哈希表都会遇到冲突,两种情况下解决冲突的方法应该一致。

下面以创建哈希表为例,说明解决冲突的方法。

1.开放寻址法

    这种方法也称再散列法,其基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。这种方法有一个通用的再散列函数形式:Hi=(H(key)+di)%m   i=1,2,…,m-1,其中H(key)为哈希函数,m 为表长,di称为增量序列,i为碰撞次数。增量序列的取值方式不同,相应的再散列方式也不同。增量序列主要有以下几种:

    (1) 线性探测再散列

        di=1,2,3,…,m-1

        这种方法的特点是:冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。

    (2)二次探测再散列

        di=12,-12,22,-22,…,k2,-k2( k<=m/2 )

        这种方法的特点是:冲突发生时,在表的左右进行跳跃式探测,比较灵活。

    (3)伪随机探测再散列

        di=伪随机数序列。

    线性探测再散列的 优点 是:只要哈希表不满,就一定能找到一个不冲突的哈希地址,而二次探测再散列和伪随机探测再散列则不一定。线性探测再散列容易产生“二次聚集”,即在处理同义词的冲突时又导致非同义词的冲突。

    其实除了上面的几种方法,开放寻址法还有很多变种,不过都是对di有不同的表示方法。(如双散列探测法:di=i*h2(k))

2.再哈希法

    这种方法是同时构造多个不同的哈希函数:Hi=RHi(key),i=1,2,3,…,n。

    当哈希地址H1=RH1(key)发生冲突时,再计算H2=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。

 3.链地址法(拉链法)

    这种方法的基本思想是将所有哈希地址相同的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表(数组)中,因而查找、插入和删除主要在同义词链中进行。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。链地址法适用于经常进行插入和删除的情况。

     拉链法的优点

        与开放寻址法相比,拉链法有如下几个优点:

            (1)拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;

            (2)由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;

            (3)开放寻址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中理论上可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;(散列表的装填因子定义为:α= 填入表中的元素个数 / 散列表的长度)

注:HashMap默认装填因子是0.75。

            (4)在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放寻址法构造的散列表,删除结点不能简单地将被删结点的空间置为空,否则将截断在它之后填入散列表的同义词结点的查找路径。这是因为各种开放寻址法中,空地址单元都被理解没有查找到元素。 因此在用开放寻址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。

     拉链法的缺点

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

4、建立公共溢出区

    这种方法的基本思想是:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表(在这个方法里面是把元素分开两个表来存储)。

    散列表的查找过程基本上和造表过程相同。一些关键码可通过散列函数转换的地址直接找到,另一些关键码在散列函数得到的地址上产生了冲突,需要按处理冲突的方法进行查找。在介绍的三种处理冲突的方法中,产生冲突后的查找仍然是给定值与关键码进行比较的过程。所以,对散列表查找效率的量度,依然用平均查找长度来衡量。

    查找过程中,关键码的比较次数,取决于产生冲突的多少,产生的冲突少,查找效率就高,产生的冲突多,查找效率就低。因此,影响产生冲突多少的因素,也就是影响查找效率的因素。

影响产生冲突多少有以下三个因素:

    1. 散列函数是否均匀;

    2. 处理冲突的方法;

    3. 散列表的装填因子。

     散列表的装填因子

        定义为:α= 填入表中的元素个数 / 散列表的长度

        α是散列表装满程度的标志因子。由于表长是定值,α与"填入表中的元素个数"成正比,所以,α越大,填入表中的元素较多,产生冲突的可能性就越大;α越小,填入表中的元素较少,产生冲突的可能性就越小。

        实际上,散列表的平均查找长度是装填因子α的函数,只是不同处理冲突的方法有不同的函数。

    这个HASH算法不是大学里数据结构课里那个HASH表的算法。这里的HASH算法是密码学的基础,了解了hash基本定义,就不能不提到一些着名的hash算法,MD5 和 SHA-1 可以说是目前应用最广泛的Hash算法,而它们都是以 MD4 为基础设计的。

Hash算法在信息安全方面的应用主要体现在以下的3个方面:

     ⑴  文件校验

        我们比较熟悉的校验算法有奇偶校验和CRC校验,这2种校验并没有抗 数据篡改 的能力,它们一定程度上能检测出数据传输中的信道误码,但却不能防止对数据的恶意破坏。

        MD5 Hash算法的"数字指纹"特性,使它成为目前应用最广泛的一种文件完整性 校验和 (Checksum)算法,不少Unix系统有提供计算md5 checksum的命令

     ⑵  数字签名

        Hash 算法也是现代密码体系中的一个重要组成部分。由于非对称算法的运算速度较慢,所以在 数字签名 协议中,单向散列函数扮演了一个重要的角色。对 Hash 值,又称"数字摘要"进行数字签名,在统计上可以认为与对文件本身进行数字签名是等效的。而且这样的协议还有其他的优点。

     ⑶ 鉴权协议

        如下的鉴权协议又被称作挑战--认证模式:在传输信道是可被侦听,但不可被篡改的情况下,这是一种简单而安全的方法。

    一致性哈希表简称DHT,主要应用于分布式缓存中,可以用来解决分布式存储结构下动态增加和删除节点所带来的问题。比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的hash方法,将数据映射到具体的节点上,如key%N(key是数据的key,N是机器节点数),如果有一个机器加入或退出这个集群,则所有的数据映射都无效了,如果是持久化存储则要做数据迁移,如果是分布式缓存,则其他缓存就失效了。

判定哈希算法好坏的四个定义 :

    1、平衡性(Balance):平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。

    2、单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。

    3、分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。 分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。

    4、负载(Load):负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同的内容。与分散性一样,这种情况也是应当避免的, 因此好的哈希算法应能够尽量降低缓冲的负荷。

    在分布式集群中,对机器的添加删除,或者机器故障后自动脱离集群这些操作是分布式集群管理最基本的功能。如果采用常用的hash取模算法,那么在有机器添加或者删除后,很多原有的数据就无法找到了,这样严重的违反了单调性原则。接下来主要说明一下一致性哈希算法是如何设计的。

以SpyMemcached的ketama算法来说,思路是这样的:

把数据用hash函数,映射到一个很大的空间里,如图所示。数据的存储时,先得到一个hash值,对应到这个环中的每个位置,如k1对应到了图中所示的位置,然后沿顺时针找到一个机器节点B,将k1存储到B这个节点中。

如果B节点宕机了,则B上的数据就会落到C节点上,如下图所示:

这样,只会影响C节点,对其他的节点A,D的数据不会造成影响。然而,这又会造成一个“雪崩”的情况,即C节点由于承担了B节点的数据,所以C节点的负载会变高,C节点很容易也宕机,这样依次下去,这样造成整个集群都挂了。

为此,引入了“虚拟节点”的概念:即把想象在这个环上有很多“虚拟节点”,数据的存储是沿着环的顺时针方向找一个虚拟节点,每个虚拟节点都会关联到一个真实节点,如下图所使用:

图中的A1、A2、B1、B2、C1、C2、D1、D2都是虚拟节点,机器A负载存储A1、A2的数据,机器B负载存储B1、B2的数据,机器C负载存储C1、C2的数据。由于这些虚拟节点数量很多,均匀分布,因此不会造成“雪崩”现象。

‘叁’ 哈希表与哈希(Hash)算法

根据设定的 哈希函数H(key) 处理冲突的方法 将一组关键字影像到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这种表便成为 哈希表 ,这一映像过程称为哈希造表或 散列 ,所得存储位置称 哈希地址 散列地址

上面所提到的 哈希函数 是指:有一个对应关系 f ,使得每个关键字和结构中一个唯一的存储位置相对应,这样在查找时,我们不需要像传统的烂码查找算法那样进行比较,而是根据这个对应关系 f 找到给定值K的像 f(K) 。

哈希函数也可叫哈希算法,它可以用于检验信息是否相同( 文件校验 ),或兆历裤者检验信息的拥有者是否真实( 数字签名 )。

下面分别就哈希函数和族简处理冲突的方法进行讨论;

构造哈希函数的方法有很多。在介绍各种方法前,首先需要明确什么是“好” 的哈希算法。若对于关键字集合中的任一个关键字,经哈希函数映像到地址集合中任何一个地址的概率是相等的,则称此类哈希函数是 均匀的 (Uniform)哈希函数。换句话说,就是使关键字经过哈希函数得到一个“随机的地址”,以便使一组关键字的哈希地址均匀分布在整个地址区间中,从而减少冲突。
常用的构造哈希函数的方法有:

理论研究表明, 除留余数法的模 p 取不大于表长且最接近表长 m 的素数效果最好,且 p 最好取1.1 n ~ 1.7 n 之间的一个素数(n为存在的数据元素个数)

以上便是常用的6种构造哈希函数的方法,实际工作中需视不同的情况采用采用不同的哈希函数,通常考虑的因素有:

前面有提到过 均匀的哈希函数可以减少冲突,但不能避免 ,因此,如何处理冲突是哈希造表不可缺少的另一方面。

通常用的处理冲突的方法有下列几种:

在哈希表上进行查找的过程和哈希建表的过程基本一致。 给定K值,根据建表时设定的哈希函数求得哈希地址,若表中此位置上没有记录,则查找不成功;否则比较关键字,若和给定值相等,则查找成功;否则根据造表时设定的处理冲突的方案找“下一地址” ,直到找到为止。

阅读全文

与处理效率最高的哈希算法是什么相关的资料

热点内容
薯仔app下载了怎么注册 浏览:841
云服务器一般租多大 浏览:467
屏幕录制app怎么样 浏览:684
义乌市联DNS服务器地址 浏览:669
App二级页面怎么做 浏览:956
提高pdf清晰度 浏览:979
服务器网卡mac地址怎么查 浏览:114
裁决之地服务器为什么这么卡 浏览:597
民生app怎么查保险 浏览:467
单片机蓝牙驱动代码 浏览:467
php实现多选后公开 浏览:645
map中的值为数组的怎么编程 浏览:261
加密货币怎么登录 浏览:1002
如何看本机服务器实例名 浏览:388
变频器加密密码 浏览:796
美国银行加密市场 浏览:384
我的世界服务器如何tp玩家 浏览:26
app下载统计怎么找 浏览:264
荔枝app怎么看适合自己的发型 浏览:371
魔兽世界client文件夹 浏览:541