MD5密码哈希算法(c语言实现)
本人为大学生在校生,所写源码有诸多不足,希望各位多多指正。编译器为Dev C++
#include<bits/stdc++.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
unsigned int A,B,C,D,CV[4],X[16];
//明文
char M[100000]="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrsyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
//常数数组T
unsigned int 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,0x699d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xb3bfbc70,
0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391};
//压缩函数每步左循环移位位数
int y[64]={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,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,20,6,10,15,21};
//移位函数
int move(int i,unsigned int x)
{
unsigned int y;
y=x<<i;
x=y|x>>(32-i);
return x;
}
//四轮运算的函数
int F(int i)
{
unsigned int a;
a=B;
B=B+move(y[i],T[i-1]+X[i-1]+A+((B&C)|(~B&D)));
A=D;
C=B;
D=C;
return 0;
}
int G(int i)
{
unsigned int a;
a=B;
B=B+move(y[i],T[i-1]+X[(1+5*i)%16-1]+A+((B&D)|(C&~D)));
A=D;
C=B;
D=C;
return 0;
}
int H(int i)
{
unsigned int a;
a=B;
B=B+move(y[i],T[i-1]+X[(5+3*i)%16-1]+A+(B^C^D));
A=D;
C=B;
D=C;
return 0;
}
int I(int i)
{
unsigned int a;
a=B;
B=B+move(y[i],T[i-1]+X[7*i%16-1]+A+(C^(B|~D)));
A=D;
C=B;
D=C;
return 0;
}
//将字符串转为可处理的32bit字,32bit为四字节由四个字符组成,每个消息分组消耗4*16=64个字符
int code(int n,int k=16)
{
for(int i=0;i<k;i++)
{
X[i]=M[4*i+64*n]|(M[4*i+1+64*n]<<8)|(M[4*i+2+64*n]<<16)|(M[4*i+3+64*n]<<24);
}
return 0;
}
int MD5encry()
{
CV[0]=A;
CV[1]=B;
CV[2]=C;
CV[3]=D;
int j=1;
for(j;j<=16;j++)F(j);
for(j;j<=32;j++)G(j);
for(j;j<=48;j++)H(j);
for(j;j<=64;j++)I(j);
A=CV[0]+A;
B=CV[1]+B;
C=CV[2]+C;
D=CV[3]+D;
}
int main(int argc, char *argv[]) {
A=0x67452301;
B=0xEFCDAB89;
C=0x98BADCFE;
D=0x10325476;
unsigned long len=strlen(M);
int m,n;
//判断需要扩展的字符数 ,如果小于448须补齐最后一组,若大于448则多出一组
if(8*len%512<448)
{
n=8*len/512+1;
m=(512-(8*len%512))/8;
for(int i=0;i<n-1;i++)
{
code(i);
for(int j=0;j<16;j++)printf("%08x",X[j]);
}
int x=len%64;
int y=x/4;
int z=x%4;
code(n-1,y);
if(z==1)X[y]=M[64*(n-1)+4*y+1]<<24|0x800000;
if(z==2)X[y]=M[64*(n-1)+4*y+1]<<16| M[64*(n-1)+4*y+2]<<24|0x8000;
if(z==3)X[y]=M[64*(n-1)+4*y+1]<<8|M[64*(n-1)+4*y+2]<<16|M[64*(n-1)+4*y+3]<<8|0x80;
if(z==0)X[y]=0x80000000;
for(int i=y+1;i<14;i++)X[i]=0x0;
//实现小端存储数据位数
X[14]=(len<<56&0xff000000)|(len<<40&0x00ff0000)|(len<<24&0x0000ff00)|(len<<8&0x000000ff);
X[15]=(len>>56&0x000000ff)|(len>>40&0x0000ff00)|(len>>24&0x00ff0000)|(len>>8&0xff000000);
for(int j=0;j<16;j++)printf("%08x",X[j]);
MD5encry();
}
else
{
n=8*len/512+1;
m=(512-(8*len%512)+512)/8;
for(int i=0;i<n-2;i++)
{
code(i);
for(int j=0;j<16;j++)cout<<X[j];
MD5encry();
}
int x=len%64;
int y=x/4;
int z=x%4;
code(n-2,y);
if(z==1)X[y]=M[64*(n-1)+4*y+1]<<24|0x800000;
if(z==2)X[y]=M[64*(n-1)+4*y+1]<<16| M[64*(n-1)+4*y+2]<<24|0x8000;
if(z==3)X[y]=M[64*(n-1)+4*y+1]<<8|M[64*(n-1)+4*y+2]<<16|M[64*(n-1)+4*y+3]<<8|0x80;
if(z==0)X[y]=0x80000000;
for(int i=y+1;i<16;i++)X[i]=0x0;
for(int j=0;j<16;j++)printf("%08x",X[j]);
MD5encry();
for(int i=0;i<14;i++)X[i]=0x0;
X[14]=(len<<56&0xff000000)|(len<<40&0x00ff0000)|(len<<24&0x0000ff00)|(len<<8&0x000000ff);
X[15]=(len>>56&0x000000ff)|(len>>40&0x0000ff00)|(len>>24&0x00ff0000)|(len>>8&0xff000000);
for(int j=0;j<16;j++)printf("%08x",X[j]);
MD5encry();
}
cout<<endl;
printf("%08x%08x%08x%08x",A,B,C,D);
return 0;
}