十一、哈希算法

业界著名的哈希算法也有很多,比如 MD5、SHA 等。
侧重点:在实际应用中,如何用哈希算法解决问题?

一、概述

哈希算法:将任意长度的二进制值串映射为固定长度的二进制值串的映射规则

哈希值:通过原始数据映射之后得到的二进制值串

二、哈希算法的设计要求

  • (1)从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法);
  • (2)对输入数据非常敏感,哪怕原始数据只修改了一个 Bit,最后得到的哈希值也大不相同;
  • (3)散列冲突的概率要很小,对于不同的原始数据,哈希值相同的概率非常小;
  • (4)哈希算法的执行效率要尽量高效,针对较长的文本,也能快速地计算出哈希值。

示例 ==》MD5哈希算法
注:MD5 的哈希值是 128 位的 Bit 长度,为了方便表示,我把它们转化成了 16 进制编码

MD5("jiajia") = cd611a31ea969b908932d44d126d195b
MD5(" 我今天讲哈希算法!") = 425f0d5a917188d2c3c3dc85b5e4f2cb
MD5(" 我今天讲哈希算法 ") = a1fb91ac128e6aa37fe42c663971ac3d

==》无论哈希文本长度,都可得到长度相同的哈希值;
==》两个相似的文本,得到的哈希值完全不同。

三、应用

最常见的几种应用:安全加密、唯一标识、数据校验、散列函数、负载均衡、数据分片、分布式存储。

1、安全加密

终极目标:一种快速并且很难被破解的哈希算法

(1)安全加密的哈希算法

最常用:MD5(MD5 Message-Digest Algorithm,MD5 消息摘要算法)和SHA(Secure Hash Algorithm,安全散列算法)。
其他:DES(Data Encryption Standard,数据加密标准)、AES(Advanced Encryption Standard,高级加密标准)。

(2)安全加密哈希算法的要求

对用于加密的哈希算法来说,有两点格外重要:

  • 很难根据哈希值反向推导出原始数据==》防止原始数据泄露
  • 散列冲突的概率要很小

==》MD5中哈希值是固定的 128 位二进制串,能表示的数据是有限的,最多能表示 2^128 个数据,而非无限的数据。
==》即便哈希算法存在冲突,但是在有限的时间和资源下,哈希算法还是很难破解的。
==》没有绝对安全的加密

在实际的开发过程中,也需要权衡破解难度和计算时间,来决定究竟使用哪种加密算法。

2、唯一标识(信息摘要)

目标:在海量图库中,搜索一张图是否存在。

思路一:每个图像取一个唯一标识(信息摘要),eg:图片的二进制码串头取100个字节,中间取100个字节,从最后取100个字节。将这300个字节串联并通过哈希算法,得到一个哈希字符串,作为图片的唯一标识。

思路二:提升效率。把每个图片的唯一标识和相应的图片文件在图库中的路径信息,都存储在散列表中。当要查看某个图片是否在图库时,先通过哈希算法对图片取唯一标识,然后再散列表中查找是否存在该唯一标识。若不存在,则说明不在图库中;若存在,可通过散列表中存储的文件路径获取图片,跟现在要插入的图片进行全量的比对,看是否完全一样。若一样,则说明已存在;若不同,则说明两张图片虽唯一标识相同,但不是相同的图片。

3、数据校验

目标:如何检验文件块的安全、正确、完整?

思路
通过哈希算法,对 100 个文件块分别取哈希值,并且保存在种子文件中。
==》哈希函数对数据敏感
==》当文件块下载完成之后,通过相同的哈希算法,对下载好的文件块逐一求哈希值,然后跟种子文件中保存的哈希值比对。如果不同,说明这个文件块不完整或者被篡改了,需要再重新从其他宿主机器上下载这个文件块。

4、散列函数

散列函数它对哈希算法的要求非常特别,更加看重的是散列的平均性和哈希算法的执行效率。

5、负载均衡

会话粘滞(session sticky)的负载均衡:在同一个客户端上,在一次会话中的所有请求都路由到同一个服务器上。

方法:通过哈希算法,对客户端IP地址或者会话ID计算哈希值,将取得的哈希值与服务器列表的大小进行取模运算,最终得到的值就是应该被路由到的服务器编号。

6、数据分片

(1)统计“搜索关键词”出现的次数

目标:1T的日志文件,记录用户的搜索关键词,要统计每个关键词被搜索的次数。

分析:(1) 日志很大,不能放入一台机器中;(2)一台机器处理1T数据,耗时长。

方法概述:先对数据分片,然后采取多台机器处理的方法,来提高处理速度。==》MapReduce 的基本思想

具体方法:用 n 台机器并行处理。首先从搜索记录的日志文件中,依次读取每个搜索的关键词,并通过哈希函数计算哈希值,然后跟n取模,最终得到的值,就是应该被分配到的机器编号。
==》哈希值相同的搜索关键词(也就是说,同一个搜索关键词)被分配到同一个机器上。每个机器分别计算关键词出现的次数,其和就是最终的结果。

(2)快速判断图片是否在图库中?

目标:1亿张图片,快速判断图片是否在图库中。

方法概述:同样进行数据分片==》利用多机处理(n台机器,每台机器只维护一部分图片对应的散列表)。

具体方法:每次从图库中读取一个图片,计算唯一标识,然后与机器个数n求余取模,得到的值就对应要分配的机器编号,然后将该图片的唯一标识与路径发到对应的机器构建散列表。

判断方法:通过同样的哈希算法,计算该输入图片的唯一标识,然后与机器个数n求余取模。假设得到的值为k,就去编号为k的机器构建的散列表中查找。

设备估算:散列表中每个数据单元包含两个信息:哈希值和图片文件路径。其中,通过MD5计算哈希值(长度为128bit,即16字节);路径长度上限为256字节,不妨假设其平均长度为128字节。若采用链表法来解决冲突,则还需存储指针,指针占用8字节。
==》估算:散列表中每个数据单元占用152字节
==》设备假设:内存为2G,散列表装载因子为0.75,则一台机器可以大约给1000万(2G*0.75/152)张图片构建散列表
==》对于1亿张图片来说,大约需要十几台机器。

实际:针对这种海量数据的处理问题,采取多机分布式处理==》突破单机内存、CPU等资源限制。

7、分布式存储——一致性哈希算法

情况:海量数据缓存,利用前面数据分析的思想,即通过哈希算法对数据取哈希值,然后对机器个数取模,得到的值就是应该存储的缓存机器编号。但是,在机器扩容时,所有的数据都要重新计算哈希值,然后重新搬移到正确的机器上。缓存中数据一下子都失效了,所有的数据请求都会穿透缓存,直接去请求数据库,很可能会发生 雪崩效应,压垮数据库

目标:新加入一台机器后,并不需要做大量的数据搬移。==》一致性哈希算法

方法:假设有 k 个机器,数据的哈希值范围为[0, MAX]。将整个范围划分为m个小区间(m远小于k),每个机器负责 m/k 个小区间。当有新机器加入时,将某几个小区间的数据,从原来的机器中搬移到新的机器中
==》既不用全部计算哈希、搬移数据,也保持各个机器上数据数量的均衡。

    原文作者:哈希算法
    原文地址: https://blog.csdn.net/u012736685/article/details/83826311
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞