md5的C语言实现

2018-07-20    来源:open-open

容器云强势上线!快速搭建集群,上万Linux镜像随意使用
    #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;  
    }  

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

上一篇: C实现方法经典算法之归并排序

下一篇:C实现生成n个元素的全排列