MD5的實現

閒着沒事幹,索性實現一下MD5



具體的東西,說白了,就是把原始數據+補充數據共分割成N個64位的小段,每個小段又分成16個小節,然後每個小段參與一次四輪運算,用ABCD這四個數關聯起他們,保證數據有絲毫變動,得到的MD5碼,會完全變動。






F=(x&y)|((~x)&z)

G=(x&z)|(y&(~z))

H=x^y^z

I=y^(x|(~z))

FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)
GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<<<s)
HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<<<s)
 II(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<<<s)

unsigned int    A=0x67452301UL;
unsigned int    B=0xEFCDAB89UL;
 unsigned int   C=0x98BADCFEUL;
unsigned int    D=0x10325476UL;


四輪循環N次,每i次取第i個分割裏的m[16]參與運算,最後得到ABCD四個值,A佔4個字節,記爲A1A2A3A4

最後按A4A3A2A1B4B3B2B1C4C3C2C1D4D3D2D1取16進制輸出即得到md5碼



//四輪循環

{

a=A;

b=B;

c=C

d=D;

FF(a,b,c,d,m[0],7,0xd76aa478);//a,b,c,d不用解釋,m[0]是每個分割出來的64字節段的其中32位的一塊,7任意數,0xd76aa478是(2^32)*abs()
        FF(d,a,b,c,m[1],12,0xe8c7b756);
        FF(c,d,a,b,m[2],17,0x242070db);
        FF(b,c,d,a,m[3],22,0xc1bdceee);
        FF(a,b,c,d,m4],7,0xf57c0faf);
        FF(d,a,b,c,m[5],12,0x4787c62a);
        FF(c,d,a,b,m[6],17,0xa8304613);
        FF(b,c,d,a,m[7],22,0xfd469501) ;
        FF(a,b,c,d,m[8],7,0x698098d8) ;
        FF(d,a,b,c,m[9],12,0x8b44f7af) ;
        FF(c,d,a,b,m[10],17,0xffff5bb1) ;
        FF(b,c,d,a,m[11],22,0x895cd7be) ;
        FF(a,b,c,d,m[12],7,0x6b901122) ;
        FF(d,a,b,c,m[13],12,0xfd987193) ;
        FF(c,d,a,b,m[14],17,0xa679438e) ;
        FF(b,c,d,a,m[15],22,0x49b40821);


GG(a,b,c,d,m[1],5,0xf61e2562);
        GG(d,a,b,c,m[6],9,0xc040b340);
        GG(c,d,a,b,m[11],14,0x265e5a51);
        GG(b,c,d,a,m[0],20,0xe9b6c7aa) ;
        GG(a,b,c,d,m[5],5,0xd62f105d) ;
        GG(d,a,b,c,m[10],9,0x02441453) ;
        GG(c,d,a,b,m[15],14,0xd8a1e681);
        GG(b,c,d,a,m[4],20,0xe7d3fbc8) ;
        GG(a,b,c,d,m[9],5,0x21e1cde6) ;
        GG(d,a,b,c,m[14],9,0xc33707d6) ;
        GG(c,d,a,b,m[3],14,0xf4d50d87) ;
        GG(b,c,d,a,m[8],20,0x455a14ed);
        GG(a,b,c,d,m[13],5,0xa9e3e905);
        GG(d,a,b,c,m[2],9,0xfcefa3f8) ;
        GG(c,d,a,b,m[7],14,0x676f02d9) ;
        GG(b,c,d,a,m[12],20,0x8d2a4c8a);
 


HH(a,b,c,d,m[5],4,0xfffa3942);
        HH(d,a,b,c,m[8],11,0x8771f681);
        HH(c,d,a,b,m[11],16,0x6d9d6122);
        HH(b,c,d,a,m[14],23,0xfde5380c) ;
        HH(a,b,c,d,m[1],4,0xa4beea44) ;
        HH(d,a,b,c,m[4],11,0x4bdecfa9) ;
        HH(c,d,a,b,m[7],16,0xf6bb4b60) ;
        HH(b,c,d,a,m[10],23,0xbebfbc70);
        HH(a,b,c,d,m[13],4,0x289b7ec6);
        HH(d,a,b,c,m[0],11,0xeaa127fa);
        HH(c,d,a,b,m[3],16,0xd4ef3085);
        HH(b,c,d,a,m[6],23,0x04881d05);
        HH(a,b,c,d,m[9],4,0xd9d4d039);
        HH(d,a,b,c,m[12],11,0xe6db99e5);
        HH(c,d,a,b,m[15],16,0x1fa27cf8) ;
        HH(b,c,d,a,m[2],23,0xc4ac5665);


II(a,b,c,d,m[0],6,0xf4292244) ;
        II(d,a,b,c,m[7],10,0x432aff97) ;
        II(c,d,a,b,m[14],15,0xab9423a7);
        II(b,c,d,a,m[5],21,0xfc93a039) ;
        II(a,b,c,d,m[12],6,0x655b59c3) ;
        II(d,a,b,c,m[3],10,0x8f0ccc92) ;
        II(c,d,a,b,m[10],15,0xffeff47d);
        II(b,c,d,a,m[1],21,0x85845dd1) ;
        II(a,b,c,d,m[8],6,0x6fa87e4f) ;
        II(d,a,b,c,m[15],10,0xfe2ce6e0);
        II(c,d,a,b,m[6],15,0xa3014314) ;
        II(b,c,d,a,m[13],21,0x4e0811a1);
        II(a,b,c,d,m[4],6,0xf7537e82) ;
        II(d,a,b,c,m[11],10,0xbd3af235);
        II(c,d,a,b,m[2],15,0x2ad7d2bb);
        II(b,c,d,a,m[9],21,0xeb86d391);


      A+=a; B+=b; C+=c; D+=d;


}

附上代碼。代碼還有很多問題。但是懶得改了,。。湊合看吧

typedef unsigned int uint;
class MD5
{
    public:
    MD5(char *str=NULL);
    unsigned char* GET(){return MD;}
    void PUT();
    uint F(uint x,uint y,uint z){return (x&y)|((~x)&z);}
    uint G(uint x,uint y,uint z){return (x&z)|(y&(~z));}
    uint H(uint x,uint y,uint z){return x^y^z;}
    uint I(uint x,uint y,uint z){return y^(x|(~z));}
    uint FF(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt);
    uint GG(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt);
    uint HH(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt);
    uint II(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt);
    uint mov(uint x,int ss){};
    private:
    int N,M;
    static uint t[64];//值爲4294967295*abs(sin(i))的整數部分
    static int s[16];//循環左移s
    uint **p;
    uint A,B,C,D;
    uint a,b,c,d;
    unsigned char MD[16];
};
//  FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)
//  GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<<<s)
//  HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<<<s)
//  II(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<<<s)
void MD5::PUT()
{
    for(int i=0;i<16;i++)
        printf("%x",MD[i]);
    cout<<endl;
}
uint MD5::FF(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt)
{
    uint mid,qut;
    mid=a+F(b,c,d)+m+tt;
    qut=mid;
    mid>>=(32-tt);
    qut<<=tt;
    qut^=mid;
    a=b+qut;
    return a;
}
uint MD5::GG(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt)
{
    uint mid,qut;
    mid=a+F(b,c,d)+m+tt;
    qut=mid;
    mid>>=(32-tt);
    qut<<=tt;
    qut^=mid;
    a=b+qut;
    return a;
}
uint MD5::HH(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt)
{
    uint mid,qut;
    mid=a+F(b,c,d)+m+tt;
    qut=mid;
    mid>>=(32-tt);
    qut<<=tt;
    qut^=mid;
    a=b+qut;
    return a;
}
uint MD5::II(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt)
{
    uint mid,qut;
    mid=a+F(b,c,d)+m+tt;
    qut=mid;
    mid>>=(32-tt);
    qut<<=tt;
    qut^=mid;
    a=b+qut;
    return a;
}
MD5::MD5(char *str)
{
    A=0x67452301UL;
    B=0xEFCDAB89UL;
    C=0x98BADCFEUL;
    D=0x10325476UL;
    int m=strlen(str),z=0;
    N=m/64+1;
    M=m%64;
    /*-----------------分配內存-----------------*/
    p=new  uint*[N];
    for(int i=0;i<N;i++)
        p[i]=new uint[16];
    for(int i=0;i<N;i++)
        for(int j=0;j<16;j++)
            p[i][j]=0;
    /*-----------------構造分組---------------*/
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<64;j++)
        {
             if(z==m)
            {
                p[i][j/4]<<=8;
                p[i][j/4]^=128;
                for(;j<64;j++)
                    p[i][j/4]<<=8;
                break;
            }
            p[i][j/4]<<=8;
            p[i][j/4]^=str[z++];
        }

    }
    /*------------------四輪運算-------------------*/
    for(int i=0;i<N;i++)
    {
        a=A;
        b=B;
        c=C;
        d=D;
        for(int j=0;j<16;j++)
        {
            FF(a,b,c,d,p[i][j],s[i],t[16*i+j]);
            uint o=a;
            a=b;
            b=c;
            c=d;
            d=o;
        }
        for(int j=0;j<16;j++)
        {
            GG(a,b,c,d,p[i][j],s[i],t[16*i+j]);
            uint o=a;
            a=b;
            b=c;
            c=d;
            d=o;
        }
        for(int j=0;j<16;j++)
        {
            HH(a,b,c,d,p[i][j],s[i],t[16*i+j]);
            uint o=a;
            a=b;
            b=c;
            c=d;
            d=o;
        }
        for(int j=0;j<16;j++)
        {
            II(a,b,c,d,p[i][j],s[i],t[16*i+j]);
            uint o=a;
            a=b;
            b=c;
            c=d;
            d=o;
        }
        A+=a;
        B+=b;
        C+=c;
        D+=d;
//        cout<<"A="<<A<<endl;
//        cout<<"B="<<B<<endl;
//        cout<<"C="<<C<<endl;
//        cout<<"D="<<D<<endl;
    }
    /*---------------四輪運算完成--------------*/


    /*---------------構造MD5輸出碼----------------*/
    int i;
    for(i=0;i<4;i++)
    {
        MD[i]=MD[i+4]=MD[i+8]=MD[i+12]=0;
        MD[i]=MD[i]^(A>>(i*8));
        MD[i+4]=MD[i+4]^(B>>(i*8));
        MD[i+8]=MD[i+8]^(C>>(i*8));
        MD[i+12]=MD[i+12]^(D>>(i*8));
    }
//    cout<<"A="<<A<<endl;
//    cout<<"B="<<B<<endl;
//    cout<<"C="<<C<<endl;
//    cout<<"D="<<D<<endl;
}
uint  MD5::t[64]={
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
};
int MD5::s[16]={
7,12,17,22,
5,9,14,20,
4,11,16,32,
6,10,15,21
};


發佈了36 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章