完整的代码如下:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define SHIFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476
unsigned int strlength = 0;
unsigned int tempA = 0, tempB = 0, tempC = 0, tempD = 0;
//定义k数组,用于压缩函数
const unsigned int k[] = {
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 };
//用数组存储向左位移数,方便操作
const unsigned int s[] = { 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21 };
//用于转换16进制
const char str16[] = "0123456789abcdef";
//循环加工函数
void MD5_circle(unsigned int MW[]) {
int f = 0, mingwen_index = 0;
int a = tempA, b = tempB, c = tempC, d = tempD;
//确定选取第一个明文
for (int i = 0; i < 64; i++) {
if (i<16) {
f = F(b, c, d);
mingwen_index = i;
}
else if (i<32) {
f = G(b, c, d);
mingwen_index = (5 * i + 1) % 16;
}
else if (i<48) {
f = H(b, c, d);
mingwen_index = (3 * i + 5) % 16;
}
else {
f = I(b, c, d);
mingwen_index = (7 * i) % 16;
}
//位置调整的赋值运算
unsigned int tmp = d;
d = c;
c = b;
b = b + SHIFT((a + f + k[i] + MW[mingwen_index]), s[i]);
a = tmp;
}
//每轮循环后,将tempA,tempB,tempC,tempD分别加上a,b,c,d,然后进入下一循环。
tempA = a + tempA;
tempB = b + tempB;
tempC = c + tempC;
tempD = d + tempD;
}
//输出加密后的16进制密文
string Ouput(unsigned int num) {
unsigned int b;
string tmp;
string str = "";
for (int i = 0; i<4; i++) {
tmp = "";
b = ((num >> i * 8) % (1 << 8)) & 0xff; //逆序处理每个字节
for (int j = 0; j < 2; j++) {
tmp.insert(0, 1, str16[b % 16]);
b = b / 16;
}
str += tmp;
}
return str;
}
int main(){
cout<<"你想测试的组数"<<endl;
int Cnt;
cin>>Cnt;
getchar();
while(Cnt--){
cout<<endl;
cout<<endl;
cout<<"输入明文:"<<endl;
string str;
getline(cin,str);
//1.处理原文 转化为二进制 并进行填充等操作
//以512位,64个字节为一组, num表示组数
cout<<"字符串长度 "<<str.length()<<endl;
unsigned int num = ((str.length() + 8) / 64) + 1;
cout<<"一共分成几组 "<<num<<endl;
strlength = num * 16;
//对于一组需要16个整数来存储 strByte表示此字符串的2进制表示
unsigned int *strBin = new unsigned int[strlength];
for (unsigned int i = 0; i < strlength; i++) {
strBin[i] = 0;
}
for (unsigned int i = 0; i <str.length(); i++) {
strBin[i / 4] |= (str[i]) << ((i % 4) * 8);
}
//尾部添加1+补全0
strBin[str.length() / 4] |= 0x80 << (((str.length() % 4)) * 8);
//补最后64位
strBin[num * 16 - 2] = str.length() * 8;
cout<<"填充完整后的二进制表示"<<endl;
for(int i=0;i<strlength;i++){
//正常填充输出
unsigned int hex1 = ( strBin[i] & 0xFF000000)>>24;
unsigned int hex2 = ( strBin[i] & 0x000000FF)<<24;
unsigned int hex3 = ( strBin[i] & 0x00FF0000)>>8;
unsigned int hex4 = ( strBin[i] & 0x0000FF00)<<8;
unsigned int hexSum = hex1 + hex2 + hex3 + hex4;
int j;
for(j=sizeof(hexSum)*8-1; j>=0; j--)
printf( "%d", (hexSum >> j) & 0x01 );
cout<<endl;
}
//2.循环加工
//初始化
tempA = A;
tempB = B;
tempC = C;
tempD = D;
//根据明文的分组进行的外层循环
for (int i = 0; i<strlength / 16; i++) {
//明文分成16份
unsigned int MW[16];
for (int j = 0; j<16; j++) {
MW[j] = strBin[i * 16 + j];
}
//进行循环加工
MD5_circle(MW);
}
//3.输出
cout<<endl;
cout << "MD5加密后的密文:" << Ouput(tempA)<< Ouput(tempB)<<Ouput(tempC)<<Ouput(tempD)<< endl;
}
}
运行结果截图如下:
网络在线加密结果: