MD5的C++实现

来源:互联网 发布:arp协议端口号 编辑:程序博客网 时间:2024/06/16 08:51

MD5 简介

对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
在MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448。因此,信息的位长(Bits Length)将被扩展至N*512+448,N为一个非负整数,N可以是零。填充的方法如下,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充(无论开始是否满足,先填充,再看满足与否)。然后,在这个结果后面附加一个以64位二进制表示的填充前信息长度。经过这两步的处理,现在的信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍,将补充后的数据以512bit分成i个分组,每次的运算都由前一轮的128位结果值和第i块512bit值进行运算。初始的128位值为初试链接变量
需要注意的是端的规则,这让我对此也有了比较深刻的认识
具体详细伪代码过程可百度百科或者维基百科,我的注释应该比较清楚了
/**<md5>.cpp Version<1.0> <Oct.23,2013>**copyright(cpp) 2013-2014 <XXX>(SNO:XXXXX).*all rights reserved. */#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<memory.h>using namespace std;//The max length of strings we will deal with#define MAXLEN 10000//rename some data typestypedef unsigned int uint32t;typedef unsigned char byte;//declare some global variables that will be used in the later//array k will store const num array( 4294967296*abs(sin(i))intergral part)uint32t k[64];int ord[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};  //ord array store const num in 64 runs//link variable in the begininguint32t A=0x67452301,B= 0xefcdab89,C= 0x98badcfe,D= 0x10325476;//16 byte 16*8=128 bits,will store final informationbyte finalMess[16];//pad array store bits will append to the original data to get length%512=448//a message will append 1bit at least,append 512 bits at most//0x80=128=10000000,first bit is 1,others is 0byte pad[64]={0x80};//char array will reflcate num to unm system at the base of 16char Hex[16]=   {  '0','1','2','3',      '4','5','6','7',      '8','9','a','b',      'c','d','e','f'   };//functions statmentsvoid initial();void encrypt(byte* str,int len);int changeNumBytes( byte str[],int len);int changeSourceTobit( char str[],int len);uint32t F(uint32t a,uint32t b, uint32t c){ return ((a&b)|((~a)&c)) ;}uint32t G(uint32t a,uint32t b, uint32t c){ return ( (a&c)|(b&(~c)));}uint32t H(uint32t a,uint32t b, uint32t c){ return a^b^c;}uint32t I(uint32t a,uint32t b, uint32t c){ return (b^(a|(~c))) ;}void setBit(uint32t w[],char str[]);void changeInt2byte(uint32t* input,byte* output,int length );void changeByte2Int( byte* input,uint32t* ouput, int length);int main(){//data declaration,source is char array get input// s is unsigned char array with the same content of source     byte s[MAXLEN];    char source[MAXLEN];    int len;    initial();//initial const data    while(gets(source) )    {//get length of input as bytes;        len=strlen(source);//copy content from source to s        memcpy(s,source,len);//change length of message to len%64==56 bytes        len=changeNumBytes(s,len);//encrypt data using md5 method        encrypt(s,len);    }}void initial(){         long long coef=1;     coef=coef<<32;    for( int i=0; i<64; i++)        k[i]=floor( abs( sin(i+1) )*(coef) );}//if length>2^32,this wil get errorint changeNumBytes( byte str[],int len){    int add;    uint32t count[2];//count represent 64bit int of length    count[0]=len<<3; //len<<3=len*8,the num of bits instead of bytes    count[1]=0;//I assume length less than 2^32    byte bits[8];      add=len<56?(56-len):(120-len%64);    memcpy(str+len,pad,add);//change count to byte in little-endian    changeInt2byte(count,bits,8);    memcpy(str+len+add,bits,8);    return len+add+8;}void encrypt( byte str[], int len){    int n_blocks=len/64;    int block_ord,i,j;    uint32t value[4];    uint32t temp_a=A;    uint32t temp_b=B;    uint32t temp_c=C;    uint32t temp_d=D;    for( block_ord=0; block_ord<n_blocks; block_ord++)    {        uint32t words[16];        changeByte2Int(str+64*block_ord,words,64);              uint32t a=A,b=B,c=C,d=D;        uint32t f,g,temp;                for( i=0; i<64; i++)        {            if( 0<=i && i<=15)                f=F(b,c,d),g=i;            else if( 16<=i && i<32)                f=G(b,c,d),g=(5*i+1)%16;            else if( 32<=i && i<48 )                f=H(b,c,d),g=(3*i+5)%16;            else                f=I(b,c,d),g=(7*i)%16;            temp=d;            d=c;            c=b;            b+=((a+f+k[i]+words[g])<<ord[i] |(a+f+k[i]+words[g])>>(32-ord[i]));            a=temp;                 }        temp_a+=a;        temp_b+=b;        temp_c+=c;        temp_d+=d;    }    value[0]=temp_a;    value[1]=temp_b;    value[2]=temp_c;    value[3]=temp_d;       changeInt2byte(value,finalMess,16);    for( j=0; j<16; j++)    {        cout<<Hex[finalMess[j]/16];        cout<<Hex[finalMess[j]%16];    }    cout<<endl;  }void changeInt2byte(uint32t* input,byte* output, int length){      for(int i=0,j=0;j<length;++i,j+=4)      {        output[j]=(byte)(input[i]&(0xff));         output[j+1]=(byte)(input[i]>>8 & 0xff);         output[j+2]=(byte)(input[i]>>16 &0xff);         output[j+3]=(byte)(input[i]>>24 & 0xff);      }}//change byte into 32bit unsigned int as liitle-endianvoid changeByte2Int(byte* input, uint32t* output,int length){     for(int i=0,j=0; j<length; ++i,j+=4)     {        output[i]= (((uint32t)input[j] ) | (((uint32t)input[j+1] )<<8) |                       (((uint32t)input[j+2] ) <<16) | (((uint32t)input[j+3])<<24) );     }}


原创粉丝点击