MD5算法加密的过程

什么是 MD5MD5 是一种算法, MD5 中的 MD 代表 Message Digest, 也即信息摘要.
至于数字 5, 则因它是从更早的 MD4 算法改进而来, 因此得名 MD5.
所以 MD5 即是信息摘要算法第五版.
什么是信息摘要算法
那什么又是信息摘要算法呢? 它本质上就是一个哈希函数(hash function).
又叫散列函数.
那什么又是哈希函数呢? 它是指这样一种函数: 它能把任意大小的数据映射(map)为一个固定大小的值.
A hash function is any function that can be used to map data of arbitrary size to fixed-size values.
哈希函数所返回的这个值称为哈希值(hash value), 又称为哈希码(hash codes), 或直接简称为哈希(hash).
具体例子
单纯地这样去讲会比较抽象, 因此这里引入具体例子来说明, 以 Java 为例, 可以这样去计算 MD5:
public void rawMd5() throws NoSuchAlgorithmException {byte[] bytes = "hello".getBytes(StandardCharsets.UTF_8);MessageDigest md = MessageDigest.getInstance("MD5");byte[] md5 = md.digest(bytes);}注: 因为摘要计算的输入是一个字节数组, 如果要计算字符串的摘要值, 则要转成某种编码的字节数组, 为保持一致, 应始终显式使用同一种编码, 比如 utf-8.
从以上代码中也不难看出, 一个 MD5 函数的输入和输出都是字节数组 byte[].
而代码中不能直接体现的一点则是: 输入可以是任意大小的字节数组, 输出则是固定大小的字节数组.
对于 MD5 算法而言, 这个输出值是一个固定大小为 16 字节的数组, 然后因为每个字节(byte)有 8 个位(bit), 所以最终的输出值是一个 16 × 8 = 128 位的二进制数. MD5 的值就是一个 128 位的二进制大整数.
比如下面就是一个具体的 MD5 的值, 以原始的 128 位二进制形式表示: 10001000100100011001000111110000100011111000000111010010110010101100010111101010000110011011110000111011111101111101100110111110
这个 MD5 值实际是对我的网站域名 xiaogd.net 作摘要的结果.
这个值的二进制形式实在是长得不要不要的, 所以一般会转换为十六进制形式, 共 16 组具体为: 88 91 91 f0 8f 81 d2 ca c5 ea 19 bc 3b f7 d9 be. 依然还是很长, 但比二进制好多了.
随便说一句, IPv6 的地址也是 128 bit 的, 所以也是像这般变态的长, 写成 16 进制也还是很长, 压根记不住...
最后通常还会去掉空格写成一个紧凑的 32 个字符的字符串的形式: 889191f08f81d2cac5ea19bc3bf7d9be, 也即是我们最常见到的 MD5 值的形式.
但请不要误解, MD5 的值并不是一个字符串, 更不是什么字母都能出现在里边的.
术语和符合本文中一个“字”是32位 , 一个“字节”是8位 。
我们定义x_i代表“x减去I".如果减数是一个表达式 , 则用括号括住 , 如:x_{i+1} 。 同样我们用^代表求幂 , 这样x^i则代表x的i次幂 。 “+”代表“字”之间的相加 , X<<< s代表X左移s位 , not(X)表示对X进行按位补运算 , X v Y表示按位或 。 X xor Y表示按位异或 , XY表示按位与 。
MD5算法描述我们假设有一个b位长的信息作为输入 , 然后我们算出他的摘要信息 。 b是一个非负整数 , b有可能是0 , 不需要一定是8的倍数 , 可能会非常得大 。 我们将输入信息描绘如下:
m_0 m_1 .. m_{b-1}
接下来的五步我们来算出它的摘要 。
1、 填充
我们将输入信息填充到长度对512取余对于448 。 无论输入信息的长度多少 , 填充总是会发生的 , 即使本身的长度就已经满足模512对于448的情况下 。
过程如下:
在输入信息后添加一个“1”位 , 其余添加“0”位使得输入信息长度满足对512取余对于448 。 总的来说 , 至少添加一位 , 至多添加512位 。
MD5算法加密的过程文章插图