青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

MD5算法的C++實現

Posted on 2008-06-25 17:12 RichardHe 閱讀(283) 評論(0)  編輯 收藏 引用 所屬分類: [轉]
來自http://m.shnenglu.com/ant/archive/2007/09/11/31886.html

MD5算法的C++實現

1. Introduction
MD5算法是一種消息摘要算法(Message Digest Algorithm),此算法以任意長度的信息(message)作為輸入進行計算,產生一個128-bit(16-byte)的指紋或報文摘要(fingerprint or message digest)。 兩個不同的message產生相同message digest的幾率相當小,從一個給定的message digest逆向產生原始message更是困難(不過據說我國的某個教授很善于從message digest構造message),因此MD5算法適合用在數字簽名應用中。MD5實現簡單,在32位的機器上運行速度也相當快,當然實際應用也不僅僅局 限于數字簽名。

2. MD5 Algorithm Description
假設輸入信息(input message)的長度為b(bit),我們想要產生它的報文摘要,在此處b為任意的非負整數:b也可能為0,也不一定為8的整數倍,且可能是任意大的長度。設該信息的比特流表示如下:

          M[0] M[1] M[2] ... M[b-1]

計算此信息的報文摘要需要如下5步:
2.1 Append Padding Bits
信息計算前先要進行位補位,設補位后信息的長度為LEN(bit),則LEN%512 = 448(bit),即數據擴展至
K*512+448(bit)。即K*64+56(byte),K為整數。補位操作始終要執行,即使補位前信息的長度對512求余的結果是448。具體補位操作:補一個1,然后補0至滿足上述要求。總共最少要補1bit,最多補512bit。

2.2 Append Length
將 輸入信息的原始長度b(bit)表示成一個64-bit的數字,把它添加到上一步的結果后面(在32位的機器上,這64位將用2個字來表示并且低位在 前)。當遇到b大于2^64這種極少的情況時,b的高位被截去,僅使用b的低64位。經過上面兩步,數據就被填補成長度為512(bit)的倍數。也就是 說,此時的數據長度是16個字(32byte)的整數倍。此時的數據表示為:

          M[0 ... N-1]

其中的N是16的倍數。

2.3 Initialize MD Buffer
用一個四個字的緩沖器(A,B,C,D)來計算報文摘要,A,B,C,D分別是32位的寄存器,初始化使用的是十六進制表示的數字,注意低字節在前:

        word A: 01 23 45 67
        word B: 89 ab cd ef
        word C: fe dc ba 98
        word D: 76 54 32 10


2.4 Process Message in 16-Word Blocks
首先定義4個輔助函數,每個函數的輸入是三個32位的字,輸出是一個32位的字:

        F(X,Y,Z) = XY v not(X) Z
        G(X,Y,Z) = XZ v Y not(Z)
        H(X,Y,Z) = X xor Y xor Z
        I(X,Y,Z) = Y xor (X v not(Z))

NOTE:not(X)代表X的按位補運算,X v Y 表示X和Y的按位或運算,X xor Y代表X和Y的按位異或運算,XY代表X和Y的按位與運算。

具體過程如下:
 1 /* Process each 16-word block. */
 2    For i = 0 to N/16-1 do
 3 
 4      /* Copy block i into X. */
 5      For j = 0 to 15 do
 6        Set X[j] to M[i*16+j].
 7      end /* of loop on j */

 8 
 9      /* Save A as AA, B as BB, C as CC, and D as DD. */
10      AA = A
11      BB =
 B
12      CC =
 C
13      DD =
 D
14 

15      /* Round 1. */
16      /* Let [abcd k s i] denote the operation
17           a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */

18      /* Do the following 16 operations. */
19      [ABCD  0  7  1]  [DABC  1 12  2]  [CDAB  2 17  3]  [BCDA  3 22  4]
20      [ABCD  4  7  5]  [DABC  5 12  6]  [CDAB  6 17  7]  [BCDA  7 22  8
]
21      [ABCD  8  7  9]  [DABC  9 12 10]  [CDAB 10 17 11]  [BCDA 11 22 12
]
22      [ABCD 12  7 13]  [DABC 13 12 14]  [CDAB 14 17 15]  [BCDA 15 22 16
]
23 

24      /* Round 2. */
25      /* Let [abcd k s i] denote the operation
26           a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */

27      /* Do the following 16 operations. */
28      [ABCD  1  5 17]  [DABC  6  9 18]  [CDAB 11 14 19]  [BCDA  0 20 20]
29      [ABCD  5  5 21]  [DABC 10  9 22]  [CDAB 15 14 23]  [BCDA  4 20 24
]
30      [ABCD  9  5 25]  [DABC 14  9 26]  [CDAB  3 14 27]  [BCDA  8 20 28
]
31      [ABCD 13  5 29]  [DABC  2  9 30]  [CDAB  7 14 31]  [BCDA 12 20 32
]
32 

33      /* Round 3. */
34      /* Let [abcd k s t] denote the operation
35           a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */

36      /* Do the following 16 operations. */
37      [ABCD  5  4 33]  [DABC  8 11 34]  [CDAB 11 16 35]  [BCDA 14 23 36]
38      [ABCD  1  4 37]  [DABC  4 11 38]  [CDAB  7 16 39]  [BCDA 10 23 40
]
39      [ABCD 13  4 41]  [DABC  0 11 42]  [CDAB  3 16 43]  [BCDA  6 23 44
]
40      [ABCD  9  4 45]  [DABC 12 11 46]  [CDAB 15 16 47]  [BCDA  2 23 48
]
41 

42      /* Round 4. */
43      /* Let [abcd k s t] denote the operation
44           a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */

45      /* Do the following 16 operations. */
46      [ABCD  0  6 49]  [DABC  7 10 50]  [CDAB 14 15 51]  [BCDA  5 21 52]
47      [ABCD 12  6 53]  [DABC  3 10 54]  [CDAB 10 15 55]  [BCDA  1 21 56
]
48      [ABCD  8  6 57]  [DABC 15 10 58]  [CDAB  6 15 59]  [BCDA 13 21 60
]
49      [ABCD  4  6 61]  [DABC 11 10 62]  [CDAB  2 15 63]  [BCDA  9 21 64
]
50 

51      /* Then perform the following additions. (That is increment each
52 
        of the four registers by the value it had before this block
53         was started.) */

54      A = A + AA
55      B = B +
 BB
56      C = C +
 CC
57      D = D +
 DD
58 

59    end /* of loop on i */

2.5 Output
報文摘要的產生后的形式為:A,B,C,D。也就是低位字節A開始,高位字節D結束。

3. C++ Implementation
有了上面5個步驟的算法描述,用C++實現起來就很直接了。需要注意的是在具體實現的時候上述5個步驟的順序會有所變動,因為在大多數情況下我們都無法或很難提前計算出輸入信息的長度b(如輸入信息來自文件或網絡)。因此在具體實現時Append Padding BitsAppend Length這兩步會放在最后面。

4. Test Suite
由于實現代碼比較長,在這里就不貼出來了,在本文后面會提供下載。MD5類的public接口如下:
md5.h
 1 class MD5 {
 2 public
:
 3 
    MD5();
 4     MD5(const void *
input, size_t length);
 5     MD5(const string &
str);
 6     MD5(ifstream &
in);
 7     void update(const void *
input, size_t length);
 8     void update(const string &
str);
 9     void update(ifstream &
in);
10     const byte*
 digest();
11 
    string toString();
12     void
 reset();
13 
    ...
14 };

下面簡單介紹一下具體用法:
1.計算字符串的MD5值
下面的代碼計算字符串"abc"的MD5值并用cout輸出:
1 MD5 md5;
2 md5.update("abc"
);
3 cout << md5.toString() <<
 endl;
4 //或者更簡單點

5 cout << MD5("abc").toString() << endl;

2.計算文件的MD5值
下面的代碼計算文本文件"D:\test.txt"的MD5值并用cout輸出,如果是二進制文件打開的時候記得要指定ios::binary模式。另外需要注意的是用來計算的文件必須存在,所以最好在計算前先判斷下ifstream的狀態。
(本來判斷ifstream是否有效不該是客戶的責任,原本想在ifstream無效時用文件名做參數拋出FileNotFoundException之類的異常,后來卻發現從ifstream中居然無法得到文件名...)
1 MD5 md5;
2 md5.update(ifstream("D:\\test.txt"
));
3 cout << md5.toString() <<
 endl;
4 //或者更簡單點

5 cout << MD5(ifstream("D:\\test.txt")).toString() << endl;

3.最基本的用法
上面的用來計算字符串和文件MD5值的接口都是為了方便才提供的,其實最基本的接口是:
void update(const void *input, size_t length);
update的另外兩個重載都是基于它來實現的,下面的代碼用上述接口來實現FileDigest函數,該函數用來計算文件的MD5值:
 1 string FileDigest(const string &file) {
 2 

 3     ifstream in(file.c_str(), ios::binary);
 4     if (!
in)
 5         return ""
;
 6 

 7     MD5 md5;
 8 
    std::streamsize length;
 9     char buffer[1024
];
10     while (!
in.eof()) {
11         in.read(buffer, 1024
);
12         length =
 in.gcount();
13         if (length > 0
)
14 
            md5.update(buffer, length);
15 
    }
16 
    in.close();
17     return
 md5.toString();
18 }

下面看看測試代碼:
test.cpp
 1 #include "md5.h"
 2 #include <iostream>
 3 
 4 using namespace std;
 5 

 6 void PrintMD5(const string &str, MD5 &md5) {
 7     cout << "MD5(\"" << str << "\") = " << md5.toString() <<
 endl;
 8 
}
 9 

10 int main() {
11 

12     MD5 md5;
13     md5.update(""
);
14     PrintMD5(""
, md5);
15 

16     md5.update("a");
17     PrintMD5("a"
, md5);
18 

19     md5.update("bc");
20     PrintMD5("abc"
, md5);
21 

22     md5.update("defghijklmnopqrstuvwxyz");
23     PrintMD5("abcdefghijklmnopqrstuvwxyz"
, md5);
24 

25     md5.reset();
26     md5.update("message digest"
);
27     PrintMD5("message digest"
, md5);
28 

29     md5.reset();
30     md5.update(ifstream("D:\\test.txt"
));
31     PrintMD5("D:\\test.txt"
, md5);
32 

33     return 0;
34 }

測試結果:
MD5("") = d41d8cd98f00b204e9800998ecf8427e
MD5("a") = 0cc175b9c0f1b6a831c399e269772661
MD5("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
MD5("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5("D:\test.txt") = 7ac66c0f148de9519b8bd264312c4d64



posts - 94, comments - 138, trackbacks - 0, articles - 94

Copyright © RichardHe

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            1024亚洲| 亚洲高清视频在线| 国产精品日韩精品| 午夜精品久久久久久久久久久久久| 你懂的网址国产 欧美| 久久精品国产免费| 美国成人直播| 欧美日韩高清免费| 国产精品一二三| 国产一区香蕉久久| 亚洲人线精品午夜| 亚洲综合精品四区| 久久久亚洲欧洲日产国码αv| 久久精品免费| 亚洲国产影院| 亚洲男人的天堂在线| 国产午夜精品一区二区三区视频| 国产女主播一区二区| 经典三级久久| 亚洲精品一区二区在线观看| 在线视频免费在线观看一区二区| 午夜精品久久久99热福利| 久久一区激情| 亚洲国语精品自产拍在线观看| 日韩亚洲成人av在线| 午夜一级在线看亚洲| 欧美成人精品h版在线观看| 国产精品自拍在线| 亚洲免费高清视频| 久久久久www| 日韩亚洲一区二区| 久久久亚洲成人| 欧美亚日韩国产aⅴ精品中极品| 精品成人a区在线观看| 亚洲天堂偷拍| 欧美电影在线免费观看网站| 亚洲一区在线看| 免费欧美在线| 激情欧美国产欧美| 欧美一区二区三区在| 99国产成+人+综合+亚洲欧美| 久久久噜噜噜久久人人看| 欧美婷婷六月丁香综合色| 91久久精品国产91性色| 久久躁狠狠躁夜夜爽| 亚洲欧美韩国| 国产精品盗摄一区二区三区| 亚洲巨乳在线| 亚洲高清中文字幕| 六月婷婷一区| 有码中文亚洲精品| 久久久久久一区二区| 亚洲一区在线直播| 国产精品国产福利国产秒拍| 一本色道久久综合亚洲91| 欧美激情在线观看| 久久久亚洲精品一区二区三区 | 亚洲高清在线精品| 国产亚洲电影| 欧美在线播放一区| 一区二区日韩欧美| 欧美四级电影网站| 亚洲天堂第二页| 日韩午夜免费视频| 国产精品国产三级国产a| 亚洲天堂偷拍| 亚洲主播在线观看| 国产精品综合久久久| 午夜精品久久久久久久99樱桃| 亚洲午夜91| 国产亚洲人成a一在线v站| 久久久人成影片一区二区三区| 午夜精品久久久久久久男人的天堂| 国产精品久久久久77777| 欧美一区二区黄色| 久久久999精品| 91久久嫩草影院一区二区| 亚洲韩国精品一区| 欧美午夜女人视频在线| 久久超碰97中文字幕| 久久久久久夜| 一区二区三区欧美亚洲| 亚洲女女女同性video| 伊人久久婷婷| 999亚洲国产精| 国产日韩在线不卡| 亚洲国产精品第一区二区三区| 欧美日韩在线免费| 久久国产直播| 欧美区在线播放| 欧美自拍偷拍午夜视频| 久久综合综合久久综合| 亚洲视频在线观看| 久久久人成影片一区二区三区| 亚洲欧洲日产国产网站| 亚洲午夜在线视频| 亚洲国产精选| 亚洲校园激情| 亚洲乱码久久| 久久爱另类一区二区小说| 亚洲精品视频在线播放| 亚洲一区观看| 亚洲美女黄色片| 久久成人亚洲| 午夜精品福利一区二区三区av | 久久不见久久见免费视频1| 老司机午夜精品视频| 亚洲欧美国产精品va在线观看| 久久精品夜夜夜夜久久| 亚洲综合色视频| 欧美成人蜜桃| 久久免费视频一区| 国产精品视频一二三| 最新成人av网站| 在线观看欧美日韩国产| 亚洲制服欧美中文字幕中文字幕| 最新国产精品拍自在线播放| 香蕉久久精品日日躁夜夜躁| 中文无字幕一区二区三区| 欧美激情视频一区二区三区不卡| 亚洲精品国久久99热| 狠狠色噜噜狠狠狠狠色吗综合| 99视频精品| 一本色道久久88精品综合| 久久夜色精品国产噜噜av| 欧美中文字幕第一页| 欧美天天在线| 一区二区三区四区精品| 亚洲视频一区二区免费在线观看| 免费不卡亚洲欧美| 欧美电影电视剧在线观看| 在线观看国产精品淫| 久久久国产精品一区二区中文 | 亚洲国产美女| 亚洲精品无人区| 免费欧美日韩国产三级电影| 欧美国产先锋| 亚洲精品乱码久久久久久蜜桃麻豆| 毛片av中文字幕一区二区| 欧美大胆a视频| 亚洲美女诱惑| 欧美日韩中文字幕| 亚洲午夜久久久久久久久电影网| 性高湖久久久久久久久| 国产精品亚洲综合天堂夜夜| 亚洲综合成人婷婷小说| 欧美影院成年免费版| 狠狠色综合网| 欧美h视频在线| 99视频一区| 欧美一区二区三区的| 国模吧视频一区| 欧美91视频| 宅男噜噜噜66一区二区| 久久国产毛片| 亚洲人成免费| 国产精品视频内| 久久天天躁夜夜躁狠狠躁2022 | 欧美亚洲网站| 麻豆精品网站| 亚洲毛片av在线| 国产精品久久久久久久久借妻| 亚洲欧美另类在线| 欧美成人综合| 亚洲欧美在线免费观看| 尤物在线观看一区| 欧美日韩伦理在线| 欧美一区二区三区四区在线观看地址| 麻豆av一区二区三区| 99综合精品| 国产亚洲精品aa| 欧美精品在线极品| 欧美影院在线播放| 亚洲人成网站777色婷婷| 欧美一区二区黄色| 亚洲精品自在久久| 国产一区二区三区四区在线观看 | 裸体一区二区| 亚洲尤物精选| 亚洲区中文字幕| 国户精品久久久久久久久久久不卡| 久久久精品久久久久| 国产欧美日韩亚洲精品| 久久精品视频99| 亚洲午夜精品久久| 亚洲欧洲精品一区二区三区| 亚洲欧美精品在线观看| 最新成人av在线| 激情欧美一区二区| 国产麻豆91精品| 欧美日韩免费一区二区三区视频| 久久久国产视频91| 亚洲女人天堂av| 一本一道久久综合狠狠老精东影业| 美女爽到呻吟久久久久| 欧美一级成年大片在线观看| 伊人狠狠色j香婷婷综合| 国产精品久久久久久av下载红粉| 欧美二区乱c少妇| 久久免费视频观看|