MD5

简单的求MD5值的程序

 

 

#include<iostream.h>
#include<string.h>
#include<fstream.h>
static const unsigned char X[64] =       //4轮处理中分别按照不同的次序使用16个字
{
     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
};

static const unsigned char cls[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,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
};

static const unsigned int T[64] =             //常数表T
{
     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
};


//4轮处理过程中使用的不同的基本逻辑函数F,G,H,I
unsigned int F(unsigned int b,unsigned int c,unsigned int d);
unsigned int G(unsigned int b,unsigned int c,unsigned int d);
unsigned int H(unsigned int b,unsigned int c,unsigned int d);
unsigned int I(unsigned int b,unsigned int c,unsigned int d);

 

void main(){
 unsigned char string[1000]={0};//初始化字符串数组
 cin.getline(string,1000);
 unsigned int len=strlen((char *)string);//获得字符串长度
    unsigned int i,j,k,t;

/*******处理过程有以下几步:*********/


//********(1)对消息填充 
 if(len>=56)//对信息进行分组(512位一组)并填充
  t=(len/64+2)*16;
 else
  t=(len/64+1)*16;
    string[len]=0x80;  //在消息后面第一位填充一个1,剩余的已经初始化为0了

   
//*******(2)附加消息的长度,将消息用字的形式保存
 unsigned int * num;
 num=new unsigned int[t];
 i=j=0; 
 while(j<t-2)
 {
  num[j++]=string[i]+string[i+1]*0x100+string[i+2]*0x10000+string[i+3]*0x1000000;
  i+=4;
 }
 num[t-1]=len*8/0x10000;                  //保存原始长度高32位
 num[t-2]=(len*8)%0x10000;               //保存原始长度低32位


//*******(3)对MD缓冲区初始化
 unsigned int IV[4]={0x67452301,0xefcdab89,0x98badcfe,0x10325476};//四个初始量
 unsigned int sta[4];
 sta[0]=IV[0]; sta[1]=IV[1];  sta[2]=IV[2];  sta[3]=IV[3];


//*******(4)以分组为单位对消息进行处理
 unsigned int temp;
 for(i=0;i<t;i+=16)//(t/16)个分组
 {
  //对每一分组,都经过一个压缩函数H(md5)处理
  for(j=0;j<4;j++)//每组分成4个32bit的字
  {
   for(k=0;k<16;k++)//进行16轮计算
   {
    //四轮处理用到不同的逻辑函数
    if(j==0)        //第一轮
     temp=F(sta[1],sta[2],sta[3]);
    if(j==1)        //第二轮
     temp=G(sta[1],sta[2],sta[3]);
    if(j==2)        //第三轮
     temp=H(sta[1],sta[2],sta[3]);
    if(j==3)        //第四轮
     temp=I(sta[1],sta[2],sta[3]);

    sta[0]+=temp+num[i+X[16*j+k]]+T[16*j+k];//压缩函数中的迭代运算
    sta[0]=(sta[0]<<cls[16*j+k])|(sta[0]>>(32-cls[16*j+k]));//循环左移
    sta[0]+=sta[1];//得到的值再与B异或
    temp=sta[3];     //换位D->A,A->B,B->C,C->D                                                 
    sta[3]=sta[2];
    sta[2]=sta[1];
    sta[1]=sta[0];
    sta[0]=temp;
   }
  }
  for(k=0;k<4;k++)    //生成下一轮的初始值
  {
   sta[k]+=IV[k];
   IV[k]=sta[k];
  }
 }


//********(5)输出
 for(i=0;i<4;i++)
 {
    cout<<hex<<sta[i];//16进制输出

 }
 cout<<endl;
 
}

//四种不同的逻辑函数
unsigned int F(unsigned int b,unsigned int c,unsigned int d)
{
 unsigned int  t=(b&c)|((~b)&d);
 return t;
}
unsigned int G(unsigned int b,unsigned int c,unsigned int d)
{
 unsigned int  t=(b&d)|(c&(~d));
 return t;
}
unsigned int H(unsigned int b,unsigned int c,unsigned int d)
{
 unsigned int  t=(b^c^d);
 return  t;
}
unsigned int I(unsigned int b,unsigned int c,unsigned int d)
{
 unsigned int  t=c^(b|(~d));
 return t;
}

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值