MD5加密算法的实现(代码+思路-->参考其他博客+修改)

完整的代码如下:

#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;
	}
}

运行结果截图如下:
在这里插入图片描述
网络在线加密结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值