首先感谢雁渡寒潭,它的一篇博客让我读懂了md5源码,本来打算把那篇文档地址复制到此,但链接已无效请见谅。
MD5 算法描述
首先我们假设我们有一个b位的输入信息,我们想获得其报文摘要。这里 b 是任意非负整数;b可以是0,且不需要是8的整数倍,而且可以任意大。
我们将报文的位写成如下形式:
m_0 m_1 ... m_{b-1}
下面的五步将得到报文的报文摘要。
Step 1. 添加填充位报文将被“填补”(扩展),以使它的长度(以位计算)以512为模同余448。就是 说,扩展报文以使它被512除之后余64。填充总是执行的,即使报文已经以512为模同余448。
填充以如下方式进行:单个“1”bit附加到报文,之后附加“0”bits以使附加后的消息的长度(以位记)达到以512为模同余448。最终,最少1bit最多512bit被附加。
Q:“填充总是执行的”如何理解?
A:假定待处理数据最后一个分组长度小于512bit,在最后一位添加0x80结束标志位,至于为什么以0x80做结束位,
个人猜测是跟摘要结果长度固定为128=8*16有关吧。如果此时长度<448bit,则把从结束标志位到448这部分全部填0。
如果原数据+结束标志>448,则把这个分组剩余部分全部填0,进行一次摘要运算,然后再建立一个分组,0-448bit全部填0。
Step 2. 附加长度
以64-bit 表示的b(还没有附加填充字节之前的长度)被附加了前一步产生的结果。
有时候b大于2^64 ,那么只有低位的64位被采用了。(这些bits被附加两个32bit的words,低位顺序,与先前的习惯一样。)
到此时为止报文(在附加bits和b之后)的长度恰好是512bits的整数倍。同样的,这个报文的长度也是16words的整数倍。
令M[0... N-1]表示消息的结果报文,这里N是16的整数倍。
Q:能否形象的举个栗子来说明?
A: 1、假定要处理的内容是“abc”,则待处理数据填充后只有一个分组:
61 62 63 80 00 00 00 00 00 00 00 00 00 00 00 00 //第一个补0x80
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 //3个字节24位,16进制表示为0x18, 小端序存放2、假定要处理的内容是"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
待处理数据填充后有2个分组,第一个分组如下:
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
第二个分组如下:35 36 37 38 39 30 31 32 33 34 35