Hash可以将大范围映射到小范围,检查输入数据或文件,也可以用于搜索具体;识别或数据验证:它可以验证输入的数据或文件,以确定它们是否相同或被修改。比如对于图像识别,可以对图像二进制流进行汇总和MD5,得到的哈希值可以作为图像的唯一标识;比如文件识别,当服务器接受文件上传时,比较两次传输文件的哈希值,如果相同,则不需要再次上传(传统的奇偶校验、CRC校验可以在一定程度上检测和纠正数据传输中的通道错误,但没有抵抗数据篡改的能力)。
加密:MD5或SHA对敏感数据(如密码字段)进行加密传输。哈希算法还可以检查信息的所有者是否真实。比如用保存密码的哈希值代替保存密码,基本可以消除泄露的风险。
数字签名。由于非对称算法运算速度慢,单向哈希函数在数字签名协议中占有重要地位。哈希值的数字签名,也称为“数字摘要”,在统计上可以视为等同于文件本身的数字签名。
哈希函数:是构造哈希表的关键。它直接决定了哈希碰撞的概率和哈希表的性质。但相比哈希算法的其他应用,哈希函数对哈希冲突的要求较低,当冲突发生时,可以通过开放寻址方法或链表方法解决。对哈希值能否逆向解密的要求不高。而是更注重哈希的均匀性,即哈希值是否均匀落入槽内,哈希函数执行的快慢也会影响哈希表性能。所以哈希函数一般比较简单,追求统一性和高效率。
负载均衡:常用的负载均衡算法有很多,如轮询、随机、加权轮询等。如何实现会话粘性负载均衡算法?可以通过哈希算法计算出客户端的IP地址的哈希值,对得到的哈希值和服务器列表的大小进行模运算,最终得到应该路由到的服务器号。这样,同一个IP的客户端请求就可以发送到同一个后端服务器。
数据碎片化:比如如何解决1T日志文件中“搜索关键词”数量的统计问题?我们可以先把日志切片,然后用多机处理来提高处理速度。依次从搜索日志中读取搜索关键字,通过哈希函数计算哈希值,然后取模n(机器数),最后的值就是应该分配的机器号。这样,哈希值相同的关键词被分在同一台机器上进行处理。每台机器分别统计关键词出现的次数,然后合并得到最终结果。这也是MapReduce的基本思想。例如,在图像识别应用中,每个图像的抽象信息被唯一地识别,然后构建哈希表。如果图库中有大量图片,那么单机的哈希表就会过大,超过单机的内存容量。这时候你也可以利用碎片化的思想,准备N台机器,每台机器负责哈希表中的一部分数据。每次从图库中取一张图片,都会计算唯一标识符,然后用机器数n取模,得到的值就是分配的机器数,再把唯一标识符和图片路径发送到对应的机器上,建立哈希表。在搜索一张图片时,用同一个哈希函数唯一标识图片摘要信息,对n进行模运算后,得到的值K就是当前图片中存储的机器号,可以在机器的哈希表中搜索到该图片。事实上,海量数据的处理可以借助这种数据碎片化的思想,突破单机内存、CPU等资源的限制。
分布式存储:一致哈希算法解决了缓存等分布式系统的伸缩带来的大量数据移动问题。
算法的实现过程:
第一步:填充消息,将长度补足到512的倍数。后64位是报文长度的低64位(填充前的长度),必须加长(64+1~512),内容为100…0(如果报文长度为448,则填充512+64)。
第二步:分段,将结果分成512位的块:Y0,Y1,…(每个有16个32位长的字)。
第三步:计算并初始化MD buffer,一个128位常量(4个32位字),进入循环迭代,共L次。每次,一个输入128位,另一个输入512位,结果输出128位用于下一轮输入。
第四步:输出,最后一步的输出是128位的哈希结果。
hash的基本功能是提供数据的摘要或指纹,通常的使用场景是完整性检查。哈希算法有很多种。一般来说,哈希越长,安全性越高。一个安全性足够高的哈希,或者没有人能成功实现碰撞哈希,才有资格被考虑加密,这种哈希算法也叫加密哈希算法