哈希算法简介与常见的哈希生成算法
- 什么是哈希算法
- 哈希
- 哈希表
- key值与位置的映射关系
- 常见的哈希生成算法
- 折叠法
- 移位叠加
- 边界叠加
- 平方取中法
- 进制转换法
- 取模法
- 伪随机数法
- 哈希算法的特点
- 哈希算法的应用
什么是哈希算法
哈希
哈希(hash)也被称之为散列,是指将任意长度的输入的数据按照某种规则(哈希算法)来变为定长的输出的方式。这个输出也被称之为哈希(散列)值。
哈希表
哈希表(散列表)是一种根据关键码值key来获取数据的数据结构。在哈希表中,在哈希表中,每一个位置都与这个key值一一映射。所以该数据结构查询速度很快。
key值与位置的映射关系
key值可以使任意一种数据类型,包括但不限于int、double、char、String…而在哈希表中,数据一般是以数组的形式存储。也就是说,哈希表中数据的位置可以表示为数组的下标。所以,一般我们通过使用哈希算法将key值转化为一个规定范围内的正整数x。然后将这个key值所表示的数据存放在下标为x的位置上。
常见的哈希生成算法
首先,哈希生成算法一般都是对数值进行运算,所以,如果是其他类型的数据,一般将其转化为数字再进行运算。例如:字符/字符串类型的数据一般根据其ASCII码值转换为数字等。当数据量较大时,也会选择性的截取其的一部分。
折叠法
将key值分割为长度相同的几部分,然后求这几部分的叠加和(舍去最高位的进位)。这种方法被称之为折叠法。
折叠法被分为移位叠加和边界叠加两种方法。
移位叠加
将分割好的几部分最高位对齐,然后进行累加运算。这种方法被称为移位叠加法。例如:使用移位叠加法,将数据4568123547801257转化为不超过10000的十进制数据。
4568
1235
4780
+ 1257
= 1840
边界叠加
将分割好的几部分进行折叠对齐。即每部分的最低位与最高位对齐,若第一部分定为编号1,编号为偶数的部分逆序排列。例如:使用比边界叠加法,将数据4568123547801257转化为不超过10000的十进制数据。
4568
5321
4780
+ 7521
= 2190
平方取中法
将key值进行平方运算,然后根据需求取其平方值中间的若干位作为哈希值。例如:利用平方取中法,获取75843的哈希值,哈希值不超过10000。首先758432 = 5,752,160,649。取其中间的4位,为2160。即75843的哈希值为2160。
进制转换法
将十进制的key看做为一个x进制的数据(x一般取质数)然后将其转换为十进制数的方法被称为进制转换法。例如:使用进制转换法,生成1569的哈希值。我们取x为13,则:9 * 13 0 + 6 * 13 1 + 5 * 13 2 + 1 * 133 = 3129。即1569的哈希值为3129。
取模法
将key值对一个特定值x进行取模运算。x一般取质数。例如14656231的哈希值为:14656231 mod 103 = 52。14656231的哈希值即为52。
伪随机数法
伪随机数法是将key值经过随机算法运算后生成的结果模上数组长度作为哈希值。公式:Hash(key)=(akey+c)%length。其中:a,c为质数,length为数组长度。例如:key值为489415,伪随机数法操作如下:
Hash(489415)=(6691489415+929)%200=94。即489415的哈希值为94。
在一般情况下,计算一个数据的哈希值会将以上方法选取几种组合使用,以保证获得的哈希值足够随机。
哈希算法的特点
哈希算法具有以下的特点:
- 输入敏感:哪怕只是改动一位数字,最后获得的哈希值都会有很大的不同。
- 不可逆:在有限的时间内,很难通过哈希值推导出原本的key值。
- 一致性:相等的key值一定能获取到相同的哈希值。
- 均匀性:均匀的散列key值。
哈希算法的应用
- 哈希算法可以用来校验数据/文件是否相同。对于较大的文件或数据,可以截取其一部分,然后通过哈希算法计算哈希值。当这两个(或多个)文件的哈希值计算出来后,通过比对哈希值是否相等来判断这两个(或多个)文件是否一致。这样操作极大地减少了资源的使用和时间。
- 哈希表
- 负载均衡:比如说,现在有多个服务器。当一个请求过来时,如何分配服务器来响应这个请求?我们可以对通过这个请求的唯一标识符(如IP地址)进行操作,获取规定范围的哈希值(一般将服务器按照从0到n编号。计算哈希值的最后一步模上n+1则一定会获得服务器编号范围内的哈希值)。根据这个哈希值选取响应的服务器。
- 分布式存储:与负载均衡相似,当时当存储数据的服务器增加时,就必须重新设计哈希算法。类似这样的问题可以通过一致性哈希算法解决。
- 数据加密:因为哈希算法具有不可逆性,所以可以用来对特殊的数据进行加密。例如密码,在用户注册的时候将密码的哈希值存储在数据库内,在用户登录时可以通过比对输入的密码的哈希值与数据库中的哈希值是否相等来判断输入的密码是否相等。(但是不常用,因为哈希算法无法避免的会产生哈希碰撞问题,会降低安全性。并且有更安全、更优秀的加密算法)