MD5

本文详细介绍了一个MD5散列算法的具体实现过程,包括辅助函数的定义与使用、消息填充步骤、长度添加、变量初始化及核心的数据处理流程。通过本教程可以深入理解MD5的工作原理。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#ifndef_MD5_H
#define_MD5_H

//将4个32位整型转换为十六进制的字串
void ToString(unsigned int* Hex,char* str);
//4个辅助函数F,G,H,I
unsigned int F(unsigned int X,unsigned int Y,unsigned int Z);
unsigned int G(unsigned int X,unsigned int Y,unsigned int Z);
unsigned int H(unsigned int X,unsigned int Y,unsigned int Z);
unsigned int I(unsigned int X,unsigned int Y,unsigned int Z);
//每轮的处理函数,i 表示是第 i轮
void Turn(int i,unsigned int& A,unsigned int B,unsigned int C,unsigned int D,unsigned int K,int S,unsigned int T);
//MD5单向散列函数
void MD5(char* szMessage,unsigned int* result,const int n);


//-------------------------------MD5辅助函数的实现---------------------------------
//4个辅助函数 F,G,H,I
unsigned int F(unsigned int X,unsigned int Y,unsigned int Z)
{
return ((X&Y)|((~X)&Z));
}
unsigned int G(unsigned int X,unsigned int Y,unsigned int Z)
{
return ((X&Z)|(Y&(~Z)));
}
unsigned int H(unsigned int X,unsigned int Y,unsigned int Z)
{
return (X^Y^Z);
}
unsigned int I(unsigned int X,unsigned int Y,unsigned int Z)
{
return (Y^(X|(~Z)));
}
//每轮的处理函数
void Turn(int i,unsigned int& A,unsigned int B,unsigned int C,unsigned int D,unsigned int K,int S,unsigned int T)
{
unsigned int temp;
unsigned int m;
if(i==1)
temp = A + F(B,C,D) + K + T;
else if( i==2)
temp = A + G(B,C,D) + K + T;
else if(i==3)
temp = A + H(B,C,D) + K + T;
else if(i==4)
temp = A + I(B,C,D) + K + T;
//循环左移S位,切记切记
m = temp>>(32-S);
temp = (temp<<S)|m;
A = temp + B;
}

//把得到的128位结果转化为字符串
void ToString(unsigned int* Hex,char* str)
{
for(int i=0;i<4;i++)
{
unsigned int temp = Hex[i];
for(int j=0;j<8;j++)
{
if(j%2 == 0)
{
if(temp%16 < 10)
str[i*8+j+1] = temp%16 + '0';
else
str[i*8+j+1] = temp%16 -10 + 'A';
}
else if(j%2 == 1)
{
if(temp%16 < 10)
str[i*8+j-1] = temp%16 + '0';
else
str[i*8+j-1] = temp%16 -10 + 'A';
}
temp = temp/16;
}
}
str[32] = '/0';
}

//----------------------------------------MD5函数的实现------------------------------------

void MD5(char* szMessage,unsigned int* result,const int n)
{
if( n < 4)
{
printf("n shoule be 4!");
return ;
}
_int64 Length = 0;//消息的长度
for(int i=0;szMessage[i] != '/0';i++)
Length++;
int addition = Length%64;//
unsigned int* M = NULL;
_int64 ln;
if(addition <= 56)//
ln = (Length - addition + 56)/4 + 2;//最终的长度(以整型计算)
else
ln = (Length/64 + 2) * 16; //判断大于56时的情况

M = (unsigned int*)malloc(ln*4);
for(i=0;i<Length;i++)
{
if(i%4 == 0)
M[i/4] = (unsigned char)szMessage[i];
if(i%4 == 1)
M[i/4] += (unsigned char)szMessage[i]<<8;
if(i%4 == 2)
M[i/4] += (unsigned char)szMessage[i]<<16;
if(i%4 == 3)
M[i/4] += (unsigned char)szMessage[i]<<24;
}

//-----------------------step 1 数据填充----------------------------------
if(Length%4 == 0)
M[Length/4] = 0x80;
if(Length%4 == 1)
M[Length/4] += 0x80<<8;
if(Length%4 == 2)
M[Length/4] += 0x80<<16;
if(Length%4 == 3)
M[Length/4] += 0x80<<24;
//填零
for(i= Length/4 + 1; i<ln - 2; i++)
M[i] = 0;

//------------------------step 2 添加长度------------------------------------
//最后64位等于消息的长度(二进制的长度)(小端存储)
M[ln-1] = (Length*8)/0x100000000;
M[ln-2] = (Length*8)%0x100000000;

//------------------------step 3 初始化变量----------------------------------

unsigned int A,B,C,D;
A = 0x67452301;
B = 0xefcdab89;
C = 0x98badcfe;
D = 0x10325476;

unsigned int * T = (unsigned int*)malloc(4*65);
unsigned int * X = (unsigned int*)malloc(4*16);
for(i=1;i<65;i++)
T[i] = (unsigned int)(4294967296*fabs(sin(i)));

//--------------------------------step 4 数据处理-------------------------------------//
for(i=0;i<ln/16;i++)
{
for(int j=0;j<16;j++)
X[j] = M[16*i+j];

unsigned int AA = A;
unsigned int BB = B;
unsigned int CC = C;
unsigned int DD = D;

//--------------------第一轮----------------------
int turn =1;
int t = 1;
for(j=0;j<16;j++,t++)
{
int s = j%4;
switch(s)
{
case 0:Turn(turn,A,B,C,D,X[j],7 ,T[t]); break;
case 1:Turn(turn,D,A,B,C,X[j],12,T[t]); break;
case 2:Turn(turn,C,D,A,B,X[j],17,T[t]); break;
case 3:Turn(turn,B,C,D,A,X[j],22,T[t]); break;
}
}
//-------------------第二轮-------------------------
turn = 2;
for(j=0;j<16;j++,t++)
{
int s = j%4;
int k = (1+j*5)%16;
switch(s)
{
case 0:Turn(turn,A,B,C,D,X[k],5 ,T[t]); break;
case 1:Turn(turn,D,A,B,C,X[k],9,T[t]); break;
case 2:Turn(turn,C,D,A,B,X[k],14,T[t]); break;
case 3:Turn(turn,B,C,D,A,X[k],20,T[t]); break;
}
}
//--------------------第三轮--------------------------
turn = 3;
for(j=0;j<16;j++,t++)
{
int s = j%4;
int k = (5+j*3)%16;
switch(s)
{
case 0:Turn(turn,A,B,C,D,X[k],4 ,T[t]); break;
case 1:Turn(turn,D,A,B,C,X[k],11,T[t]); break;
case 2:Turn(turn,C,D,A,B,X[k],16,T[t]); break;
case 3:Turn(turn,B,C,D,A,X[k],23,T[t]); break;
}

}
//---------------------第四轮-----------------------------
turn = 4;
for(j=0;j<16;j++,t++)
{
int s = j%4;
int k = (0+j*7)%16;

switch(s)
{

case 0:Turn(turn,A,B,C,D,X[k],6 ,T[t]); break;
case 1:Turn(turn,D,A,B,C,X[k],10,T[t]); break;
case 2:Turn(turn,C,D,A,B,X[k],15,T[t]); break;
case 3:Turn(turn,B,C,D,A,X[k],21,T[t]); break;
}
}
A = A + AA;
B = B + BB;
C = C + CC;
D = D + DD;
}
result[0] = A;
result[1] = B;
result[2] = C;
result[3] = D;

free(X);
free(M);
free(T);
}

#endif

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值