首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

MD5的有关问题

2012-04-14 
MD5的问题C/C++ code#includeiostream#includecstring#includemath.husing namespace stdclass MD5

MD5的问题

C/C++ code
#include<iostream>#include<cstring>#include<math.h>using namespace std;class MD5{public:        int md5_value[4];//存放MD5值private:    int block,modsize,bits;    int appsize;    int F(int X,int Y,int Z){return (X&Y)|(~X&Z);}    int G(int X,int Y,int Z){return (X&Z)|(Y&~Z);}    int H(int X,int Y,int Z){return X^Y^Z;}    int I(int X,int Y,int Z){return Y^(X|~Z);}    int CountPadNum(const int);    int AddingBits(const char*,char*,int);    int RotateLeft(int x,int s){return (x<<s)|(x>>(32-s));}    void GetMd5(char*,int);protected:public:    MD5(string);    ~MD5(){};};MD5::MD5(string str=""):block(512),modsize(448),bits(8),appsize(64){    const char *pstr=str.c_str();    int padnum=CountPadNum(str.size());//计算需要填充的长度    char *pdata=new char[str.size()+padnum+appsize/bits];;//保存处理后的信息    int times=AddingBits(pstr,pdata,padnum);//循环的次数    GetMd5(pdata,times);}int MD5::CountPadNum(const int length){//512n+448    int mod=length*bits%block;    int c_bits;    if(mod==0)        c_bits=modsize;    else        c_bits=(modsize+block-mod)%block;    return c_bits/bits;}int MD5::AddingBits(const char *argv,char *pnew,int addn){    int msg_length=strlen(argv);    unsigned long long app_length=msg_length*bits;//刚好是64位,用来保存信息长度    //保存原始信息数据    strncpy(pnew,argv,msg_length);    //补全填充原始信息空间(512n+448)    unsigned char fill=0x80;//10000000    memmove(pnew+msg_length,&fill,1);    memset(pnew+msg_length+1,0,addn-1);//用ASCII为0的字符去填充    //(512n+448+64)中的64    memmove(pnew+msg_length+addn,(char*)&app_length,sizeof(long long));    return ((msg_length+addn)*bits+appsize)/block;}void MD5::GetMd5(char *pdata,int times){    int const link[4]={0x67452301,0xefcdab89,0x98badcfe,0x10325476};//四个32位链接变量    //FF(a,b,c,d,mj,s,ti)    const int m[4][2]={{0,1},{1,5},{5,3},{0,7}};//子分组的起始位和间距    const int s[4][4]={{7,12,17,22},{5,9,14,20},{4,11,16,23},{6,10,15,21}};//四轮中左循环移动位数    int (MD5::*auxi[4])(int,int,int)={&MD5::F,&MD5::G,&MD5::H,&MD5::I};//声明四个函数指针,参考自csdn论坛http://topic.csdn.net/u/20111120/09/2c3dbe74-777d-49ab-96bf-b7ea7f8ca0da.html?1069146612    int pblock[16];//存储512位信息块    int chain[4];    int state[4];    memmove((char*)chain,(char*)link,sizeof(int)*4);//第一次转存储四个32位链接变量    for(int j=0;j!=times;++j){        memmove((char*)pblock,pdata+j*block/bits,block/bits);//512位数据块,以字节为单位进行数据复制        memmove(state,chain,sizeof(int)*4);//第二次转存储四个32位链接变量        for(int r=0;r!=4;++r){//四次大循环            int mIdx=m[r][0];//数组索引头            int sIdx=0;            for(int i=0;i!=16;++i){//16次小重复                //FF(a,b,c,d,mj,s,ti) a=b+((a+F(b,c,d)+Mj+ti)<<s)                 //floor()向下取整                state[sIdx]=state[(sIdx+1)%4]+RotateLeft(state[sIdx]+(this->*auxi[r])(state[(sIdx+1)%4],state[(sIdx+2)%4],state[(sIdx+3)%4])+pblock[mIdx]+(unsigned int)floor((1ULL<<32)*fabs(sin(r*16+i+1))),s[r][i%4]);                sIdx=(sIdx+3)%4;//FF(a,b,c,d,M0,7,0xd76aa478)=》FF(d,a,b,c,M1,12,0xe8c7b756)中的a=》d                mIdx=(mIdx+m[r][1])&0xF;//1、2、3、4、5... ...            }        }        chain[0]+=state[0];        chain[1]+=state[1];        chain[2]+=state[2];        chain[3]+=state[3];    }    memmove((char*)&md5_value+0,(char*)&chain[0],sizeof(int));    memmove((char*)&md5_value+4,(char*)&chain[1],sizeof(int));    memmove((char*)&md5_value+8,(char*)&chain[2],sizeof(int));    memmove((char*)&md5_value+12,(char*)&chain[3],sizeof(int));}int main(){    string a;    cin >> a;    MD5 T(a);    cout << hex;    for(int i=0;i!=4;++i)    cout << T.md5_value[i];    cout << endl;    return 0;}

研究过MD5的大侠看一下,这个程序出了什么问题,怎么老是运行不到正确的结果,我参照百度百科MD5写的C++实现,也对照了,代码没发现什么异样,就是运行答案不正确!
求帮助!

------解决方案--------------------


C/C++ code
#include <stdio.h>#include <math.h>#include <string.h>#include <memory.h>const unsigned int s[4][4]={{7,12,17,22},{5,9,14,20},{4,11,16,23},{6,10,15,21}};const unsigned long t[64]={//t[i]=4294967296*fabs(sin(i+1));    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};const int serial[64]={    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};void func(unsigned long& a,    unsigned long b,    unsigned long c,    unsigned long d,    unsigned long M,    unsigned long t,    int s,    int turn) {        unsigned long temp;        switch(turn) {        case 0:            temp=(b&c)|((~b)&d);            break;        case 1:            temp=(d&b)|((~d)&c);            break;        case 2:            temp=b^c^d;            break;        case 3:            temp=c^(b|(~d));            break;        }        temp+=M+t+a;        _asm {            mov ecx,s                rol temp,cl        }        a=b+temp;}void MD512(const unsigned long M[16],unsigned long hash[4]) {    int i,j,index=0;    for (i=0;i<4;i++)        for (j=0;j<4;j++) {            func(hash[0],hash[1],hash[2],hash[3],M[serial[index]],t[index],s[i][0],i);            index++;            func(hash[3],hash[0],hash[1],hash[2],M[serial[index]],t[index],s[i][1],i);            index++;            func(hash[2],hash[3],hash[0],hash[1],M[serial[index]],t[index],s[i][2],i);            index++;            func(hash[1],hash[2],hash[3],hash[0],M[serial[index]],t[index],s[i][3],i);            index++;        }}void MD5(char* M,int nLen,unsigned long output[4]) {    int i,j;    unsigned long Hash[4]={0x67452301,0xefcdab89,0x98badcfe,0x10325476};    unsigned long hash[4];    //填充    __int64 BitsLen=nLen*8;    int oldlen=nLen;    while(nLen%64!=56) {        M[nLen++]=0;    }    M[oldlen]=0x80u;    *(__int64*)(M+nLen)=BitsLen;    nLen+=8;    //开始处理分组    for (i=0;i<nLen;i+=64) {        memcpy(hash,Hash,sizeof(long)*4);        MD512((const unsigned long*)&M[i],hash);//处理512bits分组        for (j=0;j<4;j++)            Hash[j]+=hash[j];    }    //处理输出。    for (i=0;i<4;i++)        for (j=3;j>=0;j--) {            *((char*)(output+i)+j)=*((char*)(Hash+i)+3-j);        }}int main() {    int i;    char szMessage[1000]={0};    printf("input a string:\n>>>");    scanf("%s",szMessage);    unsigned long output[4];    MD5(szMessage,strlen(szMessage),output);    for (i=0;i<4;i++)        printf("%08lx",output[i]);    printf("\n");    return 0;} 

热点排行