一、MD5算法简介
MD5算法是一种广泛使用的密码散列函数,可以将任意长度的文本转换成128位(16字节)的哈希值。由于哈希值的长度固定,因此可以用来验证信息的完整性和一致性。MD5算法的产生是为了取代MD4算法(由于密码分析学的进步及用户的需求,MD4的安全性已经无法保证)。
MD5算法的核心思想是将输入的信息进行分组,并按照规定的方式进行处理,最后得到一个定长的输出。它的算法是基于位运算、模2的余数运算和逻辑运算等算法的组合
二、MD5算法实现过程
1. 填充
MD5算法处理的是二进制数据,但是输入的数据往往是以字节为单位的,所以需要将输入数据按照512位(64字节)为一组进行划分,并且需要将输入的数据进行填充。 填充规则如下: (1)如果输入的数据的字节数是64的倍数,不需要填充; (2)如果输入的数据的字节数不足64字节,需要在末尾填充一个1,其余补0,直到满足64字节; (3)如果输入的数据的字节数超过64字节,需要在末尾填充一个1,其余补0,直到末尾64字节,然后将所有的64字节分组按照算法进行处理。
2. MD5算法处理
(1)初始化 定义4个32位的参数:A、B、C、D,用于存储中间状态。 每次处理512位时,先将A、B、C、D分别赋成如下值: A = 0x67452301; B = 0xefcdab89; C = 0x98badcfe; D = 0x10325476; (2)处理512位 将512位数据划分成16组,每组32位。设当前处理的一组数据为X[i],则下一组数据为X[i+1]。 (3)四轮运算 分别进行4轮运算,每轮运算都将当前结果进行迭代,迭代方式如下: 1)轮 1:F(X,Y,Z) = (X & Y) | (~X & Z); 2)轮 2:G(X,Y,Z) = (X & Z) | (Y & ~Z); 3)轮 3:H(X,Y,Z) = X ^ Y ^ Z; 4)轮 4:I(X,Y,Z) = Y ^ (X | ~Z); (4)更新中间状态 每轮运算后,都需要更新中间状态A、B、C、D。 A = A + F(B,C,D) + X[i] + T[i]; B = D; C = B; D = A; (5)最终结果 处理完所有的数据块后,将A、B、C、D拼接为一个128位的hash值,即为MD5算法处理结果。
三、使用方法
1. 环境要求
在VS2015中实现,需要用到以下头文件:
#include #include #include
由于MD5算法使用了位运算和逻辑运算,因此为了便于处理,可以使用uint32_t类型进行定义。
2. MD5算法代码实现
#include #include #include #include #include using namespace std; typedef unsigned int uint32_t; const uint32_t A = 0x67452301; const uint32_t B = 0xefcdab89; const uint32_t C = 0x98badcfe; const uint32_t D = 0x10325476; const uint32_t T[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; inline uint32_t leftrotate(uint32_t x, uint32_t n) { return x <> (32 - n); } uint32_t F(uint32_t X, uint32_t Y, uint32_t Z) { return (X & Y) | (~X & Z); } uint32_t G(uint32_t X, uint32_t Y, uint32_t Z) { return (X & Z) | (Y & ~Z); } uint32_t H(uint32_t X, uint32_t Y, uint32_t Z) { return X ^ Y ^ Z; } uint32_t I(uint32_t X, uint32_t Y, uint32_t Z) { return Y ^ (X | ~Z); } void md5(uint32_t* data, uint32_t len, uint32_t* digest) { uint32_t* X = new uint32_t[16]; uint32_t a = A; uint32_t b = B; uint32_t c = C; uint32_t d = D; for (uint32_t i = 0; i < len; i += 16) { memcpy(X, data + i, 16 * sizeof(uint32_t)); uint32_t aa = a; uint32_t bb = b; uint32_t cc = c; uint32_t dd = d; for (uint32_t i = 0; i < 64; ++i) { uint32_t f, g; if (i < 16) { f = F(b, c, d); g = i; } else if (i < 32) { f = G(b, c, d); g = (5 * i + 1) % 16; } else if (i < 48) { f = H(b, c, d); g = (3 * i + 5) % 16; } else { f = I(b, c, d); g = (7 * i) % 16; } uint32_t tmp = d; d = c; c = b; b = b + leftrotate(a + f + X[g] + T[i], 7); a = tmp; } a += aa; b += bb; c += cc; d += dd; } delete[] X; digest[0] = a; digest[1] = b; digest[2] = c; digest[3] = d; } int main() { string input = "hello world"; uint32_t* data = new uint32_t[input.size() + 64]; memcpy(data, input.c_str(), input.size()); uint32_t len = ceil(8 * input.size() / 512) * 16; memset(data + input.size(), 0, (len - input.size()) * sizeof(uint32_t)); data[input.size() / 4] |= 0x00000001 << (8 * input.size() % 32); uint32_t digest[4]; md5(data, len, digest); delete[] data; printf("MD5 hash:\n"); printf("%08x%08x%08x%08x\n", digest[0], digest[1], digest[2], digest[3]); return 0; }
3. 示例
对字符串”hello world”进行MD5加密:
input: "hello world" output: 5eb63bbbe01eeed093cb22bb8f5acdc3
完整代码如下:
#include
#include
#include
#include
#includeusing namespace std;
typedef unsigned int uint32_t;
const uint32_t A = 0x67452301;
const uint32_t B = 0xefcdab89;
const uint32_t C = 0x98badcfe;
const uint32_t D = 0x10325476;const uint32_t T[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af,
0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453,
0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681,
0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5,
0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0,
0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };inline uint32_t leftrotate(uint32_t x, uint32_t n) {
return x <> (32 - n);
}uint32_t
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/249194.html