md5的C語言實現

ngmm 10年前發布 | 1K 次閱讀 C/C++

    #include "iostream"

#include "string"  
#include "math.h"  
using namespace std;  
typedef  char byte;  

//初始化四個數  
long A=0X67452301l;  
long B=0XEFCDAB89l;  
long C=0X98BADCFEl;  
long D=0X10325476l;  




long F(long x, long y, long z){  
    return ((x & y) | ((~x) & z)) &0x0ffffffffl;  
}  

long G(long x, long y, long z){  
    return ((x & z) | (y & (~z))) &0x0ffffffffl;  
}  
long H(long x, long y, long z){  
    return (x ^ y ^ z) &0x0ffffffffl;  
}  
long I(long x, long y, long z){  
    return (y ^ (x | (~z))) &0x0ffffffffl;  
}  

 long FF(long a, long b, long c, long d, long Mj, long s, long ti) {  
    a = (a + F(b, c, d) + Mj + ti) & 0xffffffffl;  
    a = ( a << s) | (a  >> (32 - s));  
    a += b;  
    return (a&0xFFFFFFFFL);  
}  
long GG(long a, long b, long c, long d, int Mj, int s, int ti){  
    a = (a + G(b, c, d) + Mj + ti) & 0xffffffffl;  
    a = ( a << s) | (a  >> (32 - s));  
    a += b;  
    return (a&0xFFFFFFFFL);  
}  
long HH(long a, long b, long c, long d, int Mj, int s, int ti){  
    a = (a + H(b, c, d) + Mj + ti) & 0xffffffffl;  
    a = ( a << s) | (a  >> (32 - s));  
    a += b;  
    return (a&0xFFFFFFFFL);  
}  
long II(long a, long b, long c, long d, int Mj, int s, int ti){  
    a = (a + I(b, c, d) + Mj + ti) & 0xffffffffl;  
    a = ( a << s) | (a  >> (32 - s));  
    a += b;  
    return (a&0xFFFFFFFFL);  
}  

void Loops(int group[16]){  
    long a = A, b = B, c = C, d = D;  
    //第一輪循環  
    a = FF(a,b,c,d,group[0],7,0xd76aa478);  
    d = FF(d,a,b,c,group[1],12,0xe8c7b756);  
    c = FF(c,d,a,b,group[2],17,0x242070db);  
    b = FF(b,c,d,a,group[3],22,0xc1bdceee);  
    a = FF(a,b,c,d,group[4],7,0xf57c0faf);  
    d = FF(d,a,b,c,group[5],12,0x4787c62a);  
    c = FF(c,d,a,b,group[6],17,0xa8304613);  
    b = FF(b,c,d,a,group[7],22,0xfd469501);  
    a = FF(a,b,c,d,group[8],7,0x698098d8);  
    d = FF(d,a,b,c,group[9],12,0x8b44f7af);  
    c = FF(c,d,a,b,group[10],17,0xffff5bb1);  
    b = FF(b,c,d,a,group[11],22,0x895cd7be);  
    a = FF(a,b,c,d,group[12],7,0x6b901122);  
    d = FF(d,a,b,c,group[13],12,0xfd987193);  
    c = FF(c,d,a,b,group[14],17,0xa679438e);  
    b = FF(b,c,d,a,group[15],22,0x49b40821);  

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

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

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

    //把運算后結果寫回去  
    A += a , B += b, C += c, D += d;  
    A &= 0xffffffff;  
    B &= 0xffffffff;  
    C &= 0xffffffff;  
    D &= 0xffffffff;  
}  

//根據循環后ABCD的值得到MD5碼  
string getMdCode(){  
    string  codes[16]={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};  

    string code = "";  
    long a = A, b = B, c = C, d = D;  
    for (int i = 0; i < 4; i++){  
        int tmp = a & 0x0f;  
        string first = codes[tmp];  
        a >>= 4;  
        tmp = a & 0x0f;  
        string second = codes[tmp];  
        code += (second + first);  
        a >>= 4;  
    }  
    for (int i = 0; i < 4; i++){  
        int tmp = b & 0x0f;  
        string first = codes[tmp];  
        b >>= 4;  
        tmp = b & 0x0f;  
        string second = codes[tmp];  
        code += (second + first);  
        b >>= 4;  
    }  
    for (int i = 0; i < 4; i++){  
        int tmp = c & 0x0f;  
        string first = codes[tmp];  
        c >>= 4;  
        tmp = a & 0x0f;  
        string second = codes[tmp];  
        code += (second + first);  
        c >>= 4;  
    }  
    for (int i = 0; i < 4; i++){  
        int tmp = d & 0x0f;  
        string first = codes[tmp];  
        d >>= 4;  
        tmp = d & 0x0f;  
        string second = codes[tmp];  
        code += (second + first);  
        d >>= 4;  
    }  
    A=0X67452301l;  
    B=0XEFCDAB89l;  
    C=0X98BADCFEl;  
    D=0X10325476l;  

    return code;  

}  

int bitToUnsign(int b){  
    return b < 0 ? b & 0x7f + 128:b;  
}  

//將64個字節劃分成16組,每小組4個字節  
int*  divideGroup(byte *bytes, int n){  
    int *group = new int[16];  
    for (int i = 0; i < 16; i++){  
        int a1 = bitToUnsign((int)bytes[n+4*i]);  
        int a2 = (bitToUnsign((int)bytes[n+4*i+1]) << 8);  
        int a3 = (bitToUnsign((int)bytes[n+4*i+2]) << 16);  
        int a4 = (bitToUnsign((int)bytes[n+4*i+3]) << 24);  
        group[i] = a1 | a2 | a3 | a4;  
    }  
    return group;  
}  

//根據輸入信息來返回該信息對應的MD5碼  
string md5(string s){  
    long length = s.length();  
    byte *ch = new byte[length + 1];  

    for (int i = 0; i < length; i++){ //將string轉化為byte的數組  
        ch[i] = (byte)s[i];  
    }  

    long groupLength = length / 64;  

    for (int i = 0; i < groupLength; i++){  
        Loops(divideGroup(ch,i * 64));  //先分組,然后再進行循環處理  
    }  

    int remain = length % 64; //剩余的字節  
    byte rest[128];  
    long bitLength = length << 3; //信息總共有多少位  

    if (remain <=56){  
        for (int i = 0; i < remain; i++){  
            rest[i] = ch[length - remain + i];  
        }  

        if (remain < 56){  
            rest[remain] = (byte)(-128);//補1  
            for (int i = 1; i < 56 - remain; i++){  //補0,直到為56個字節(448位)  
                rest[remain + i] = 0;  
            }  
        }  
        for (int i = 56; i < 64; i++){ //補長度  
            rest[i] = (byte)(bitLength & 0xff);  
            bitLength = bitLength >> 8;  
        }  


        Loops(divideGroup(rest, 0));  
    }  
    else { //多于56個字節,則先補到120字節,再用剩余的八個字節來儲存長度  
        rest[remain] = (-128); //補1  
        for (int i = remain + 1; i < 120; i++) { //補0  
            rest[i] = 0;  
        }  
        for (int i = 120; i < 128; i++){  //補長度  
            rest[i] = (byte)(bitLength & 0xff);  
            bitLength >>= 8;  
        }  
        Loops(divideGroup(rest, 0));  
        Loops(divideGroup(rest, 64));  
    }  
    //根據運算后的ABCD返回其MD5碼  
    return getMdCode();  
}  

int main(int argc, char * argcs[]){  

    string s = "";  
    cout << md5(s) << endl;  
    s = "a";  
    cout << md5(s) << endl;  
    s = "abc";  
    cout << md5(s) << endl;  

    return 0;  
}  </pre> 


 本文由用戶 ngmm 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!