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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值