之前总是听说这两个算法,也偶尔用到,但是从来没有想过是怎么去完成的。
对于未知的恐惧,会促使人类不断的学习。然后就出现了庄子的那句名言:知识是无限的,人命是有限的,拿有限的人命去搞无限的知识,真2B啊。即便如此,有些唾手可得的知识还是可以花一些时间去看看的。
当然,首先还是wiki,这里为wiki点个赞,等咱有闲了也去写,等咱有钱了也去捐。
安全散列算法(Secure Hash Algorithm) http://zh.wikipedia.org/wiki/SHA1
消息摘要算法第五版(Message-Digest Algorithm 5,缩写为MD5)http://zh.wikipedia.org/wiki/MD5
算法我就不搬运了,反正就那么点儿,而且两个算法还是一样的。重要的是上面两个英文全称,很多正经事情都是名副其实的。
好歹说两句我的理解,不管是MD5还是SHA系列,算法都是一样的,不一样的是其中的一些细节和最后输出的长度。其中hash值的初始化和个数以及key值的初始化,这3个方面的差别,衍生出一系列的不同算法。我们最直观的就是能看到MD5是128bits的,SHA1是160bits的,以及一堆长度自明的算法,SHA224/SHA256/SHA384/SHA512,通常我们看到的字符串的长度就是上面说的bits长度除以4。凭直觉,当然是越长的越安全。对,这里的安全这个概念,其实是说的不容易“碰撞”,也就是不同的内容得到相同的hash值,这种事情是不可避免要发生的,一旦发生就可能会很糟糕。
我用直白的语言描述一下这个算法,以表明我真的看懂了。
输入是一堆数据,数据就是0和1,反正计算机里面的数据都是0和1。
数据有长短,为了处理方便,第一步就是将数据补到512的倍数长度,这补上来的部分,第一位是1,中间是0,后面是64位的表示数据真实长度的数。当然MD5是小端的,SHA系列是大端的,我也不知道为什么,反正算法里面是这样写的。
第二步就是将这512n长度的数据分成n个部分,每个部分512bits。
第三步就是循环处理每个部分,搞n次。在搞之前,会定义一堆的数h,大概可以算作hash种子吧,不过我也没看到人家怎么叫,32位的或者64位的,4个5个或者8个,反正就是看具体那个算法了。
第四步我们看这n次的每一次。将512bits的数据分成32bits*16,然后在将这16个数扩展成64个或者80个,这当然也是看算法,至于怎么扩展,就是隔着取几个,异或搞搞,循环移动搞搞,复杂的再加加减减,反正就是一些基本预算了。
第五步就是循环搞着64或者80个数,根之前定义的hash种子,每个数算出两个数来,再来来回回将hash种子小折腾一番。每搞一次,就算出一堆数,将这对数加到对应的hash种子上。
我们可以看到通过第第四步和第五步的折腾,64n次或者80n次后,最初初始化的hash种子已经面目全非了,算是hash果实了。
第六步,就是将hash果实串起来,收工。比如4个32位hash果实,串起来就得到128位的MD5。
这样我们就可以将任意长度的数据变成固定长度的信息数据,并且实际上还很难反推,从其中大量的逻辑操作就可以看出来。理论上……理论上还是可以计算的吧,就是计算量有点儿大。