哈希算法的用途
什么是哈希算法
一说到哈希算法, 我瞬间就想到了哈希函数、哈希表, 其实他们并不是一回事.
简单来说, 哈希算法就是将任意长度的字符串通过计算转换为固定长度的字符串, 不对, 不光字符串, 应该说是将任意长度的二进制串转换为固定长度的二进制串, 这个转换的过程就是哈希算法.
既然将任意长度的字符串转换成固定长度的, 那么冲突就不可避免了, 比如将0-100所有的数字, 映射到0-10这十个数字上, 难免会发生冲突. 一般来说, 计算得出的哈希值越长, 冲突的概率就越低, 比如说, 计算过后, 哈希值为16个字节, 也就是128位, 那么就有2^128个不同的哈希值, 发生哈希冲突的概率为(1/2)^128, 这个概率可以说很低了.
以MD5为例, 以下是经过MD5转换后的值:
朋友你好: 677fe16950241e74ef632efb2b9f92a7
朋友你好!: 6efa551df87d9de987f17be4e73eb720
可以看到, 哪怕仅仅差了一个感叹号, 计算后的值也是天壤之别, 所以很多网站上下载文件的同时还提供md5值, 现在能够理解了吧, 你将下载后的文件通过md5算法进行计算, 得到的字符串如果和网站给定的不相同, 说明文件被修改过了.
当然, 哈希算法不仅仅只有md5这一种, 以用途来分析哈希算法, 就不说哈希算法的原理了, 因为我不会.
1. 数据校验
上面说到的md5就是其中的一个, 好像还有一个什么SHA, 不过我不知道, 也就不展开探讨了.
md5可以将一个文件经过计算转换成一个指定长度的字符串, 可以防止文件被篡改, 但是通过加密后的字符串很难逆向推出原文.
前面那个例子可以看到, 即使文件被修改了一点点, 也会导致计算后的值发生很大变换.
2.唯一标识
比如说, 现在有十万个文件, 给你一个文件, 要你在这十万个文件中查找是否存在. 一个很笨的办法就是把每一文件都拿出来, 然后按照二进制串一一进行对比. 但是这个操作注定是比较费时的.
可以用哈希算法对文件进行计算, 然后比较哈希值是否相同. 因为存在哈希冲突的情况, 你可以在相同哈希值的文件再进行二进制串比较.
3.哈希表
在哈希表中使用哈希函数已经并不陌生了, 不再赘述.
4.负载均衡
比如说, 现在又多台服务器, 来了一个请求, 如何确定这个请求应该路由到哪个路由器呢?当然, 必须确保相同的请求经过路由到达同一个服务器. 一种办法就是保存一张路由关系的表, 比如客户端IP和服务器编号的映射, 但是如果客户端很多, 势必查找的时间会很长. 这时, 可以将客户端的唯一标识信息(如:IP、username等)进行哈希计算, 然后与服务器个数取模, 得到的就是服务器的编号.
5.分布式存储
当我们有大量数据时, 一般会选择将数据存储到多个服务器, 为了提高读取与写入的速度嘛. 决定将文件存储到哪台服务器, 就可以通过哈希算法取模的操作来得到.
但是, 如果数据多了, 要增加服务器了, 问题就来了, 比如原来是10台服务器, 现在变成15台了, 那么原来哈希值为16的文件被分配到编号6的服务器, 现在被分配到编号1的服务器, 也就意味着所有文件都要重新计算哈希值并重新非陪服务器进行存储. 一致性哈希就是这个用途, 可以查找我的历史文章.
暂时我能想到的就只有这些, 当然, 哈希算法的用途还有很多, git中的commit id等, 但是我不太了解, 就假装没有吧, 嘿嘿
有时对用户的密码进行MD5加密再保存, 确实要比明文保存好的多. 但是, 你以为通过哈希算法进行加密就万事大吉了么? 不好意思, 并不能, 像前面提到的MD5就已经号称别破解了.
比如, 你将用户的密码进行MD5加密后进行保存, 若有心人拿到你的数据库数据, 虽然得到的是加密后的密码, 但是只要准备一个常用密码的字典, 将字典中的密码进行加密后与数据库保存的数据进行比较, 如果相同, 基本上就可以确定了.
我感觉可以对密码进行双层加密, 也就是使用两个不同的加密算法, 一个算法的输出作为另一个的输入, 增大一些破解的难度吧.