⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md5.cpp

📁 MD5算法功能较简单的实现..只是对明文进行MD5加密并输出密文..
💻 CPP
字号:
// MD5.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <memory.h>
#include <iostream>

using namespace std;

#define MAX_SIZE 1000
const unsigned int s[4][4]= //循环左移的S位数表
{
	{7,12,17,22},{5,9,14,20},
	{4,11,16,23},{6,10,15,21}
}; 

//t的取值
const unsigned long t[64]={//t[i]=4294967296*fabs(sin(i+1));
    	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 int serial[64]=      //4轮M输入的顺序 
{
	0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
		1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
		5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
		0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
};
void MD5(char* M,int nLen,unsigned long output[4]);//加密总过程
void Four_Round(const unsigned long M[16],unsigned long hash[4]);//四轮加密
void func(unsigned long& a,unsigned long b,unsigned long c,unsigned long d,
		  unsigned long M,unsigned long t,int s,int turn);//a = b + ((a + Process(b,c,d) + M + t) <<< s)


void MD5(char* M,int nLen,unsigned long output[4])
{
	int i,j;
	unsigned long ABCD[4]={0x67452301,0xefcdab89,0x98badcfe,0x10325476};//链接变量ABCD
	unsigned long abcd[4];
	
	/////////////////////////////////////////////////////////
	//填充
	__int64 BitsLen=nLen*8;//位数=总字节*8
	int oldlen=nLen;//原字节数
	
	//Step 1:
	//填充100000000……使总长度为512位的倍数减去64位
	while(nLen%64!=56)//填充0使总位数nLen%64=56,512/8=64,留8个字节64位,即剩下56个字节
	{
		M[nLen++]=0;
	}
	M[oldlen]=0x80;//使填充位的第一位是1,128即为二进制的10000000
	
	//添加长度
	*(__int64*)(M+nLen)=BitsLen;//原字符串的位数
	nLen+=8;//得到填充后的字节数
	
	/////////////////////////////////////////////////////////
	//分块处理
	for (i=0;i<nLen;i+=64)//将输入分成512位的块,每次处理512位长的块
	{
		memcpy(abcd,ABCD,sizeof(long)*4);//复制abcd
		Four_Round((const unsigned long*)&M[i],abcd);//处理512bits分组
		for (j=0;j<4;j++)
			ABCD[j]+=abcd[j]; 
	}
	
	/////////////////////////////////////////////////////////
	//处理输出。
	for (i=0;i<4;i++)
		for (j=3;j>=0;j--)
		{
			*((char*)(output+i)+j)=*((char*)(ABCD+i)+3-j);//高位与低位字节交换
		}
}

///////////////////////////////////////////////////////////////////////////
//a = b + ((a + Process(b,c,d) + M + t) <<< s)
void func(unsigned long& a,unsigned long b,unsigned long c,unsigned long d,
		  unsigned long M,unsigned long t,int s,int turn)
{
	unsigned long temp;
	
	//Process(b,c,d)
	switch(turn)
	{
	case 0:
		temp=(b&c)|((~b)&d); //round 1 
		break;
	case 1:
		temp=(d&b)|((~d)&c); //round 2 
		break;
	case 2:
		temp=b^c^d;          //round 3 
		break;
	case 3:
		temp=c^(b|(~d));     //round 4  
		break;
	}
	//a = b + ((a + Process(b,c,d) + M + t) <<< s). 
	temp+=M+t+a;//temp=a + Process(b,c,d) + M + t
	_asm              //循环左移S位
	{
		mov ecx,s
			rol temp,cl
	}
	a=b+temp;
}
/////////////////////////////////////////////////////////////////////////
//
/* Do the following 16 operations. 
[ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52] 
[ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56] 
[ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60] 
[ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64] */ 
void Four_Round(const unsigned long M[16],unsigned long abcd[4])
{
	int i,j,index=0;
	for (i=0;i<4;i++)
		for (j=0;j<4;j++)
		{
			//round 1
			func(abcd[0],abcd[1],abcd[2],abcd[3],M[serial[index]],t[index],s[i][0],i);
			index++;
			//round 2
			func(abcd[3],abcd[0],abcd[1],abcd[2],M[serial[index]],t[index],s[i][1],i);
			index++;
			//round 3
			func(abcd[2],abcd[3],abcd[0],abcd[1],M[serial[index]],t[index],s[i][2],i);
			index++;
			//round 4
			func(abcd[1],abcd[2],abcd[3],abcd[0],M[serial[index]],t[index],s[i][3],i);
			index++;
		}
}


int _tmain(int argc, _TCHAR* argv[])
{
	char ch='y';
	cout<<"===============================================\n"
		<<"====  注:处理的字符串最大长度为"<<MAX_SIZE<<". ====\n"
		<<"===============================================\n"<<endl;
	do{
		int i;
		char plaintext[MAX_SIZE]={0};		
		cout<<endl<<"请输入明文: ";
		cin>>plaintext;
		unsigned long cyphertext[4];//一个unsigned long占4个字节,一个字节有8位,所以一共有4*8*4=128位
		MD5(plaintext,strlen(plaintext),cyphertext);
		printf("所得的密文: ");
		for (i=0;i<4;i++)
			printf("%08lx",cyphertext[i]);			
		cout<<"\n是否继续加密?(y/Y)  ";
		cin>>ch;
		cout<<endl;		
	}while(ch=='y'||ch=='Y');

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -