数据结构与算法之美笔记——哈希算法

摘要:

哈希算法是将不同长度二进制串转换为固定长度二进制串的算法,在加密,唯一性校验,数据分片等方面都有应用

该叫散列函数还是哈希函数

看到哈希函数时心中总是会泛起疑问,哈希算法需要单独列出,那散列函数又是什么?之前我们讨论过散列表以及散列函数,散列其实就是哈希,只是翻译的不同而已,不过散列表中的散列函数只是哈希算法的一种应用而已。

哈希算法的定义比较简单,就是将不同长度二进制串转换为固定长度(128 bit)二进制串的算法,哈希算法通过原始数据计算得到的值就是「哈希值」,虽然哈希算法的定义简单,但哈希算法在实现上有几个需要注意的原则:

  • 哈希值不能逆推原始数据
  • 哈希算法的冲突要小
  • 哈希算法执行要高效
  • 差异较小的原始数据生成的哈希值应完全不同

哈希算法具有不能逆转的特性,但哈希算法并不能完全避免哈希值冲突,因为哈希值的长度固定,128 bit 长度的数据只能保证 个数据不会有重复哈希值出现,如果使用 个数据进行哈希计算肯定会得到相同的哈希值。不过你就会想,那增加哈希值长度不就可以降低冲突的可能?这种方式确实可以降低哈希冲突的概率,但生成更长的哈希值也会使哈希算法的效率降低。在面对差异较小的数据时,哈希算法也应该生成不同的哈希值。

实际应用

由于哈希算法的特性,在实际中可以用于加密数据、验证唯一性、负载均衡、数据分片等方面,接下来详细讨论一下哈希算法的实际运用。

数据加密

在实际生产中像密码等敏感数据都不应该明文存储,明文保存的密码在数据泄漏后会使用户的登录安全荡然无存,因为哈希值的不可逆推特性可以保证原始数据的安全,所以哈希算法也被应用在数据加密方面。不过如果是过于简单的密码「000000」、「123456」等,都可以通过常用密码字典生成哈希值进行对应,以推出原始数据,所以对数据加密时可以将密码与「盐(salt)」组合后通过哈希算法计算,这样就可以使哈希值较难破解。当然,也可以选择更加复杂,更加安全的加密算法,不过算法执行效率也会相应降低。

唯一性验证

哈希算法不可逆且唯一,使其成为验证唯一性的不二选择。比如使用 BT 工具下载文件时,种子文件中记载着正确文件的哈希值,下载完成的文件会将文件内容生成哈希值与种子文件中的比对,如果比对失败那就说明文件被篡改或者被损坏,需要重新到相应服务器进行下载。有些从官网下载的文件也是会生成 MD5 码,可以与官网上记录的 MD5 码进行比较,验证文件的正确性。

图片查找

验证两个图片是否相同的办法就是比较两个图片转化的二进制数据是否完全一致,但使用这种方式在大量图片中查找相同图片效率就太过低下。其实可以截取图片数据片段生成哈希值,将哈希值与图片路径对应存储在库表中,当要查找某张图片时将传入图片进行相同的数据截取,并且生成哈希值,利用哈希值查找相应图片路径,再将路径下的图片与传入图片转换为二进制比对,这样可以极大提高图片查找的执行效率。

散列函数

正如开篇提到的,散列函数也是哈希算法的一种应用,不过它对安全性和唯一性并没有较高的要求,散列函数需要哈希值能够均匀分布,并且能够执行高效,即使有一定的冲突也可以利用开放寻址或者链表法解决,所以散列函数的计算都较为简单。

除了以上的几个方面外,在分布式场景下哈希算法也有所应用。

负载均衡

在负载均衡中有一种情况是需要同一会话路由到同一服务器,这种称为「会话粘滞(sticky session)」,简单的做法就是将会话 ID 与服务器对应存储在库表中,通过请求的会话 ID 查找应该路由到的服务器。但这种方法有些问题,当请求量增加时库表存储的数据量会不断增大,而且这种对应关系在服务器数量进行扩容或者缩容时也可能被破坏,增加了数据维护的压力。其实可以通过将会话 ID 进行哈希计算,将得到的哈希值与服务器数量取模,取模结果是多少就表示此会话路由到第几个服务器上。

数据分片

接着前面讲到的图片查找问题讨论。当图片数量过多,如果还存储在一台服务器上的话,维护图片哈希值与路径对应关系的库表就会非常大,导致不宜查找,我们可以将图片存放在不同的服务器上,此服务器只维护本机上图片哈希值与图片路径的对应关系,图片的哈希值可以与服务器数量取模确定该图片需要存储于哪台服务器,这样不仅将存储压力分散在不同服务器上,同时也将计算的压力进行了分摊。

分布式存储

如今因为数据量激增,很多数据都是分布式存储的,如果使用数据分片的方式利用哈希值取模确定数据存储于哪台服务器,那当对服务器进行扩容或者缩容的时候所有数据都需要重新计算搬移一遍,这样对于数据维护的压力过大。这里可以使用「一致性哈希算法」,我们将哈希值限定在 0 至 M 之间,假设有 n 个服务器,将哈希值区间划分为 m 个小区间,每个服务器负责 m/n 个区间的哈希值,如果增加一台服务器,就将每个服务器负责的区间数据分一部分搬移到新服务器上,这样即可以保证服务器的扩容缩容不用维护过多数据,也可以保证数据分布均匀。

总结

哈希算法拥有安全性、唯一性并且高效的特点,这些特点使其被应用在数据加密、唯一性验证、负载均衡、分布式存储等方面,其实除了上面介绍的应用场景之外哈希算法还有很多的应用场景。


文章中如有问题欢迎留言指正
数据结构与算法之美笔记系列将会做为我对王争老师此专栏的学习笔记,如想了解更多王争老师专栏的详情请到极客时间自行搜索。

你可能感兴趣的:(数据结构与算法之美笔记——哈希算法)