一、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
微信扫一扫
支付宝扫一扫