在区块链的领域里,哈希算法可谓是被提到的最多的概念之一,很多人第一次听到这个概念也是因为区块链。
那到底什么是哈希算法?除了区块链以外,哈希算法在生活中的其他领域还有那些应用呢?
维基百科关于哈希算法的解释:
> 散列函数(或散列算法,又称哈希函数,英语:Hash Function)是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值(hash values,hash codes,hash sums,或hashes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。
《区块链行业词典》的解释:
> 哈希值通常用一个短的随机字母和数字组成的字符串来代表,是一组任意长度的输入信息通过哈希算法得到的“数据指纹”。因为计算机在底层机器码是采用二进制的模式。
> 因此通过哈希算法得到的任意长度的二进制值映射为较短的固定长度的二进制值,即哈希值。此外,哈希值是一段数据唯一且极其紧凑的数值表示形式,如果通过哈希一段明文得到哈希值,哪怕只更改该段明文中的任意一个字母,随后得到的哈希值都将不同
看完这两段严谨的解释,再配以不太严谨的类比和举例,应该就能对哈希有一个更深入的认识。
哈希算法是一个函数,能够把几乎所有的数字文件都转换成一串由数字和字母构成的看似乱码的字符串。
中学我们都学过函数y=f(x),对应到哈希函数,输入任意值x,进过f函数(在这里就是哈希算法)的运算,得到一个y(在这里也叫哈希值)。
哈希函数作为一种加密函数,其拥有两个最重要特点:
* 不可逆性。输入信息得出输出的那个看似乱码的字符串(哈希值)非常容易,但是从输出的字符串反推出输入的结果却是却非常非常难。
从数学理论上来讲,函数都是可逆的,知道输出结果和函数关系,一定可以推出输入值。而现在计算机所采取的方法就是暴力破解,采取枚举的方法,一个一个试(哈希碰撞),直至试出正确的结果。
* 输出值唯一性和不可预测性。只要输入的信息有一点点区别,那么根据哈希算法得出来的输出值也相差甚远。
关于不可逆性,我们可以类比为人与指纹以及猪和香肠的关系。
* 人和指纹
找到一个人,知道他的指纹非常容易,而只知道一个人的指纹想知道他是谁却非常非常难。但是比对两个指纹是否相符却非常简单,所以警方只收集指纹没有用,还需要有一个庞大的指纹库,简单对比就知道凶手是谁。在这里,人本身就是输入值,人的基因就是算法,得出的指纹就是哈希值。
* 猪和香肠
每头猪可以做出很多香肠,想通过香肠判断是哪头猪确实很难的事情。
关于输出值唯一性,可以在这个网站体验一下。
http://www.fileformat.info/tool/hash.htm
输入“纸上得来终觉浅”,输出哈希值。MD5和SHA-256等那一列指的是哈希算法中不同的输出标准。在File Hash那里,还可以输入文件,看看输出的哈希值是否和官方提供的哈希值一致。防止有些安装包被人恶意篡改,安装之后窃取用户数据。
除了在区块链领悟,哈希算法和我们日常生活也是紧密相关的。最典型的比如银行卡密码,我的银行卡密码是“123456”,在银行后台的数据库肯定不会存储我的密码是“123456”,而是会把这个六位数字密码经过哈希算法转为会一个由数字和字母组成的字符串(8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92)SHA-256,每次我们输入密码,系统通过哈希算法生成一个字符串,只需要将这两个字符串比对。比对结果一直就说明输入的密码是正确的,如果字符串不一致就说明密码错误。
为什么密码要区分大小写字母和标点符号?
大小写字母,中英文状态下的标点符号对应的哈希值是完全不一样的,所以明文密码就需要区分,不然哈希值不对,无法验证密码正确。
bitcoin的哈希值(SHA-256)
6b88c087247aa2f07ee1c5956b8e1a9f4c7f892a70e324f1bb3d161e05ca107b
Bitcoin的哈希值(SHA-256)
b4056df6691f8dc72e56302ddad345d65fead3ead9299609a826e2344eb63aa4
虽然只是第一个字母大小写的区别,但是哈希值也是天壤之别。毫无规律可循。
看似晦涩难懂的哈希函数,如果知道是怎么运作和哪些情况用到哈希函数,就算我们不知道内部复杂的数学原理,也能感觉他非常可靠和有趣。