md5全過程詳解

參考自:http://blog.sina.com.cn/s/blog_6fe0eb1901014cpl.html#cmt_54A25B76-7F000001-6D7FA63B-829-8A0

md5詳解:
    原字符串爲N*512+R位,8位是一個字節(也叫字符)
    填充:如果R大於448,則填充不夠64位,而我們需要64位保留字節存儲字符串的原長
    原長存儲:如果長度大於64位的長度,則只存取前64位的長
    把記錄原長的64位按照小端規則(64位分高32位和低32位,如0x12則高32位爲 0x0000 0000 低32位爲 0x0000 0012 )排列放入填充好的數組(先叫它數組吧),
    分組:將每512位分成16組,即每組32位,也是4個字節,例如abcd。存入int變量時(不清出其它類型可以不,自己百度),需要注意大端小端的問題,我們看見的是大端排列的,內存中是小端排列的,md5是按內存中的小端的輸出
        一個16進制佔用4位,即8個16進製爲一組,也就是用16進製表示則爲16*8個16進制數共爲512位。也可以表示爲(4*8)*16
        例如abcde的16進制(對應ascii碼)表示爲 61 62 63 64 65 ,此時長度爲4*10=40位,不足512位,使用先補一個1再補n個0的形式補齊512位(原長與512取餘不大於448)
        abcde共5個字符,即5*8=40=0x28,即長度位爲0x2800 0000 ,0000 0000,8個16進制位一組,爲保持內存中的小端排序與前面相同,我們輸入的排列爲0000 0028 ,0000 0000
    初始化結束,開始進入計算公式和參數說明部分+
    MD5有四個32位的被稱作鏈接變量的整數參數,我們進行如下設置(默認固定的設置,下邊的是大端排序的數,在內存中的排序即是01234567 89abcdef fedcba98 76543210):
        A=0x67452301,
        B=0xefcdab89,
        C=0x98badcfe,
        D=0x10325476。
    聲明四個中間變量a,b,c,d,賦值:a = A, b = B, c = C, d = D。
        F(X,Y,Z) =(X&Y)|((~X)&Z)
        G(X,Y,Z) =(X&Z)|(Y&(~Z))
        H(X,Y,Z) =X^Y^Z
        I(X,Y,Z)=Y^(X|(~Z))
        (&是與,|是或,~是非,^是異或)
    這四個函數的說明:如果X、Y和Z的對應位是獨立和均勻的,那麼結果的每一位也應是獨立和均勻的。
    假設M[j]表示消息的第j個子分組(從0到15),這裏的 ti 也是固定的貌似,因爲看到的好幾篇文章都是相同的參數
        FF(a, b, c, d, M[j], s, ti)表示 a = b + ((a + F(b, c, d) + Mj + ti) <<< s)
        GG(a, b, c, d, M[j], s, ti)表示 a = b + ((a + G(b, c, d) + Mj + ti) <<< s)
        HH(a, b, c, d, M[j], s, ti)表示 a = b + ((a + H(b, c, d) + Mj + ti) <<< s)
        II(a, b, c, d, M[j], s, ti)表示 a = b + ((a + I(b, c, d) + Mj + ti) <<< s)
    要確保形參a在內存中的值改變了,可以在形參中用按引用調用(&a),或返回a值取代原來a值。
    準備結束,進入正式的計算部分
    這個循環的循環次數爲512位分組的個數(即之前提到的N+1或者N+2)。每次循環執行以下的步驟,我就不用文字表述了,直接用代碼展示,相信大家能理解:

    {

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

        //傳說中的對M[j]的第一輪循環

        FF(a,b,c,d,M[0],7,0xd76aa478);
        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,M[4],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);

        //傳說中對M[j]的第二輪循環
        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);

        //傳說中對M[j]的第三輪循環
        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);

        //傳說中對M[j]的第四輪循環
        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;

    }

處理完所有的512位的分組後,得到一組新的A,B,C,D的值,將這些值按ABCD的順序級聯,然後輸出。這裏還要注意,輸出的MD5是按內存中數值的排列順序,所以我們要分別對A,B,C,D的值做一個小端規則的轉換。
舉個例子:A有32位,分成4個字節A1A2A3A4。輸出A的時候,要這樣輸出:A4A3 A2A1。這樣就能輸出正確的MD5了。
下邊給幾個測試使用:
    MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
    MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
    MD5 (“ab”) = 187ef4436122d1cc2f40dc2b92f0eba0
    MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
    MD5 (“abcde”) = ab56b4d92b40713acc5af89985d4b786
    MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
    MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
    MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") = f29939a25efabaef3b87e2cbfe641315
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章