• <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>

            #ant

            The dreams in which I'm dying are the best I've ever had...

            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


            源代碼下載:點擊下載
            在這里放上Vrcats修改的Qt版本:點擊下載

            posted on 2007-09-11 12:20 螞蟻終結者 閱讀(57534) 評論(121)  編輯 收藏 引用 所屬分類: Encrypt

            評論共2頁: 1 2 

            Feedback

            # re: MD5算法的C++實現[未登錄] 2007-09-24 15:45 flyman

            現在還用不著,收藏了,免得以后費勁。  回復  更多評論   

            # re: MD5算法的C++實現 2007-10-18 10:14 MonkeyLin

            有個bug, 很小,但是不注意會導致很嚴重的問題:
            bytesToHexString return的是局部變量str, 應該把return str 改為return string(str);
            // md5.cpp: line 321-332
            string MD5::bytesToHexString(const byte *input, size_t length) {
            string str;
            str.reserve(length << 1);
            for(size_t i = 0; i < length; i++) {
            int t = input[i];
            int a = t / 16;
            int b = t % 16;
            str.append(1, HEX[a]);
            str.append(1, HEX[b]);
            }
            return str;
            }
              回復  更多評論   

            # re: MD5算法的C++實現 2007-10-18 10:27 螞蟻終結者

            @MonkeyLin
            thanks!不過我想你沒有仔細看代碼,string是按值返回的,不存在任何問題。
            如果返回值類型是string&或string*,才會出現你說的返回局部變量的問題。
            另外,return str;與return string(str);并無本質區別。
              回復  更多評論   

            # re: MD5算法的C++實現 2007-10-22 11:21 MonkeyLin

            @螞蟻終結者
            呵呵,這兩天又好好研究了下,發現是我之前不夠仔細,對c++的return理解不正確,所以搞錯了,剛學c++不久,讓大家見笑了 :-)  回復  更多評論   

            # re: MD5算法的C++實現 2007-10-22 13:24 螞蟻終結者

            @MonkeyLin
            都是學習嘛,互相討論會更有收獲呵呵。  回復  更多評論   

            # re: MD5算法的C++實現 2007-11-09 10:59 MonkeyLin

            如果要移植到64位機器上(我的是GCC4.1),要記得把
            typedef unsigned long ulong;
            改為
            typedef unsigned int ulong;
            要不然算出來的都是錯的

            64位下面的GCC4.1中int是32位,long是64位
            32位Win32下面VC7中int是32位,long是32位
            給后面的人提個醒,省得多走彎路。。。

            BTW: ICU里面的頭文件不錯, 針對不同的機器和平臺統一定義了uint32_t, int64_t這些類型,名字直觀,大大方便了移植,特別是對開發機是win32,服務器是64位其它平臺的,有興趣可以去看
            http://www.icu-project.org/  回復  更多評論   

            # re: MD5算法的C++實現 2007-11-10 10:49 螞蟻終結者

            @MonkeyLin
            thanks!
            ICU記得以前編譯Boost庫時下載過。
            在64位機器上確實會有問題,不過為了簡單,也為了減少對庫的依賴性,把
            typedef unsigned long ulong;
            改成
            typedef unsigned int uint32;
            基本就夠用了。
            已經更新了源代碼^_^  回復  更多評論   

            # re: MD5算法的C++實現 2008-03-13 16:05 gg

            用了一下這個源代碼,可是計算文件的md5值和專門軟件算出來的不一樣。。。
            這個。。。。  回復  更多評論   

            # re: MD5算法的C++實現 2008-03-14 09:14 螞蟻終結者

            @gg
            其實具體的用法在源代碼的main函數中已經演示得很清楚了,我想你也肯定沒有看文章后面的:“2.計算文件的MD5值”這一段,專門計算md5值的軟件如WinMD5是以二進制形式打開文件的,所以:

            string s1 = MD5(ifstream("file")).toString();
            string s2 = MD5(ifstream("file", ios::binary)).toString();

            s1與s2是不一樣的,前一個是以文本模式打開,后一個是以二進制模式打開。
              回復  更多評論   

            # re: MD5算法的C++實現 2008-04-11 10:03 redberries

            寫的不錯,頂下,不過覺得如果把Updata()加個返回值判斷是否成功可能會保險一點,還有就是下面的代碼好像有點小問題,這個str的最后位置是不是應該放個'\0'啊,

            // md5.cpp: line 321-332
            string MD5::bytesToHexString(const byte *input, size_t length) {
            string str;
            str.reserve(length << 1);  //str.reserve((length << 1) + 1);
            for(size_t i = 0; i < length; i++) {
            int t = input[i];
            int a = t / 16;
            int b = t % 16;
            str.append(1, HEX[a]);
            str.append(1, HEX[b]);
            }
            str[length>>1] = '\0'
            return str;
            }
              回復  更多評論   

            # re: MD5算法的C++實現 2008-04-11 10:05 redberries

            //str[length>>1] = '\0'
            呵呵
              回復  更多評論   

            # re: MD5算法的C++實現 2008-06-19 15:00 CPPLearning

            在2.2 Append Length 那塊第二行:

            “也就是說,此時的數據長度是16個字(32bit)的整數倍。”貌似應該是32bytes,:)

              回復  更多評論   

            # re: MD5算法的C++實現 2008-06-23 22:03 螞蟻終結者

            @CPPLearning
            謝謝提醒,是我的疏忽呵呵!  回復  更多評論   

            # re: MD5算法的C++實現 2008-07-04 14:50 路緣

            剛好用上,謝謝博主  回復  更多評論   

            # re: MD5算法的C++實現 2008-07-23 09:15 beejoy

            @MonkeyLin
            不會有問題的。  回復  更多評論   

            # re: MD5算法的C++實現 2008-07-24 11:22 冰蘭

            真的很好,嘻嘻,謝謝謝謝  回復  更多評論   

            # re: MD5算法的C++實現 2008-07-31 17:07 蔡火勝

            太好了,我喜歡這個東西!  回復  更多評論   

            #  你好,我編譯你的代碼后出現下面問題,能幫我看下嗎? 2008-08-18 22:14 zhengdu

            --------------------Configuration: test - Win32 Debug--------------------
            Compiling...
            test.cpp
            c:\documents and settings\administrator\桌面\md5\md5.h(47) : error C2258: illegal pure syntax, must be '= 0'
            c:\documents and settings\administrator\桌面\md5\md5.h(47) : error C2252: 'BUFFER_SIZE' : pure specifier can only be specified for functions
            c:\documents and settings\administrator\桌面\md5\md5.cpp(130) : error C2065: 'BUFFER_SIZE' : undeclared identifier
            c:\documents and settings\administrator\桌面\md5\md5.cpp(130) : error C2057: expected constant expression
            c:\documents and settings\administrator\桌面\md5\md5.cpp(130) : error C2466: cannot allocate an array of constant size 0
            c:\documents and settings\administrator\桌面\md5\md5.cpp(130) : error C2133: 'buffer' : unknown size
            執行 cl.exe 時出錯.

            test.obj - 1 error(s), 0 warning(s)
              回復  更多評論   

            # re: MD5算法的C++實現 2008-08-19 10:12 螞蟻終結者

            @zhengdu
            你用的是哪個版本的VC ?VC6.0 ?

            大概是你的編譯器太老,不支持static const整形值的初始化語法,試試下面兩種辦法:

            1. 將md5.h中的
            static const size_t BUFFER_SIZE = 1024;
            改為
            enum { BUFFER_SIZE = 1024 };

            2. 將md5.h中的
            static const size_t BUFFER_SIZE = 1024;
            改為
            static const size_t BUFFER_SIZE;

            并在md5.cpp的
            MD5::MD5() {
            reset();
            }
            上面加上
            const size_t MD5::BUFFER_SIZE = 1024;
              回復  更多評論   

            # re: MD5算法的C++實現 2008-09-01 11:37 zhongyunde

            這個代碼有問題嗎   回復  更多評論   

            # re: MD5算法的C++實現 2008-09-01 19:38 螞蟻終結者

            @zhongyunde
            代碼沒有問題,可以放心使用!  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 14:12 wx3456

            這個MD5封裝類確實很好!可是怎樣將MD5字符解密后還原成原來的字符啊?(不知道該調用那些函數)請舉例說明!最好轉換成CString類型的數據。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 14:28 螞蟻終結者

            @wx3456
            不好意思,我不太明白你說的“MD5字符解密”是什么意思?
            MD5是單向的,是沒有辦法從MD5值推算出原先的信息的。
            從string值轉換成CString很簡單,google一下有很多。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 14:55 wx3456

            我現在要做的是把用戶名和密碼的信息加密后保存在ini件當中 原來是用一個任意的字符串和要加密的字符進行異或運算進行加密,解密時在進行一次異或運算。可是這樣做后會產生一個問題的(就是會產生不可讀字符如回車,換行等等,這樣在讀ini文件時這些不可讀的字符會讀不出來)。我聽說MD5加密后的字符都是普通的可以顯示的字符所以我這才用MD5加密,可是如何把加密后的密碼字符串恢復原樣以便在用戶登錄時解密 和用戶輸入的密碼對比,如果相同則登錄成功,就是這個意思  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 15:06 螞蟻終結者

            @wx3456
            既然MD5是單向的,那你可以換一種方式:
            在用戶登錄時,計算用戶輸入的密碼的MD5值,拿這個值和ini文件里的MD5比較,如果相等就允許登錄(雖然多個不同的密碼可能對應相同的MD5值,但是幾率可以說非常小,對于一般的應用來說足夠了)。

            比如用戶A注冊時的密碼為abc,計算MD5值保存在ini文件為:
            900150983cd24fb0d6963f7d28e17f72

            在用戶A登錄時,假設用戶輸入的密碼為xxx,則計算xxx的MD5值,若和ini文件中的MD5值相等就允許登錄。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 15:12 wx3456

            恩...我覺得也是這樣,以后像前輩多多請教啊,請問前輩你是研究哪方面的啊?
              回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 15:30 螞蟻終結者

            @wx3456
            呵呵,前輩不敢當,我大學剛畢業工作才幾個月而已。目前從事C++方面的工作,有空多交流。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 16:11 foxtail

            我用了你的這個 但是算出來的MD5和網上的一些個工具不一樣啊
            你有檢查過嗎 不知道是什么原因  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 16:17 螞蟻終結者

            @foxtail
            這個是沒有問題的,參考下上面我回答的:
            @gg
            其實具體的用法在源代碼的main函數中已經演示得很清楚了,我想你也肯定沒有看文章后面的:“2.計算文件的MD5值”這一段,專門計算md5值的軟件如WinMD5是以二進制形式打開文件的,所以:

            string s1 = MD5(ifstream("file")).toString();
            string s2 = MD5(ifstream("file", ios::binary)).toString();

            s1與s2是不一樣的,前一個是以文本模式打開,后一個是以二進制模式打開。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-08 16:33 foxtail

            恩 剛才也看到gg的了 不好意思。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 12:10 ktls

            我試的也是不一樣,不知道為什么,你說要用二進制打開文件,
            string FileDigest(const string& file) {

            ifstream in(file.c_str(), ios::binary);
            if (!in) {
            return "";
            }
            這不是已經是用二進制打開的嗎,可得到的md5碼還是和winmd5的結果不一樣。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 14:11 螞蟻終結者

            @ktls
            這個我測試過很多次了,肯定是沒有問題的!
            可能是你哪個地方弄錯了!  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 15:19 wx3456

            我現在要實現的功能是用戶登錄驗證和用戶的添加,密碼修改,我把這些都保存在ini文件中的。登錄驗證是可以的,就是但我我修改某一用戶的密碼后,然后在驗證這個用戶的登錄時缺不能通過 我調試發現用戶名的加密字符對比是可以的,就是密碼加密的字符對比卻不相同的 代碼是這樣的
            md5.update(PWd.GetBuffer()); t3=md5.toString().c_str(); 其中PWD是從文本框中得到的輸入密碼,t3是CString型的變量,這樣計算出來的md5密碼是(密碼是1234)e19d5cd5af0378da05f63f891c7467af 而之前從ini文件中讀出來的是 049ec6b8b8565dfde2007f7a9f7ecd84(這個md5密碼是修改密碼后重新計算寫入的) 為什么兩者不一樣啊?導致驗證失敗  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 15:35 ktls

            我是這樣測試的,把你提供的3個文件添加到工程里去,把test.cpp里注釋掉的
            //md5.reset();
            //md5.update(ifstream("D:\\test.txt"));
            //PrintMD5("D:\\test.txt", md5);
            改成我自己的文件
            md5.reset();
            md5.update(ifstream("C:\\abc.doc"));
            PrintMD5("C:\\abc.doc", md5);
            其它沒有改過任何地方,執行如果如下:
            MD5("") = d41d8cd98f00b204e9800998ecf8427e
            MD5("a") = 0cc175b9c0f1b6a831c399e269772661
            MD5("abc") = 900150983cd24fb0d6963f7d28e17f72
            MD5("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e400
            MD5("message digest") = f96b697d7cb7938d525a2f31aaf1
            MD5("C:\abc.doc") = 8b30f9eef77e2ac08a19bb159bfe1495
            用winmd5的檢驗"c:\abc.doc"文件得到的結果如下:
            7dfe74280223aa9819f1617a5ef40643 abc.doc

            能告訴我email地址嗎,可以通過email與你討教,也方便發送測試結果。
            另外有個建議,能不能把這個做成dll,可以提供給別人直接調用。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 15:41 螞蟻終結者

            @wx3456
            有幾個地方我不太清楚,首先049ec6b8b8565dfde2007f7a9f7ecd84是什么密碼加密出來的?還有1234的md5應該是81dc9bdb52d04dc20036dbd8313ed055才對。如果方便的話把源碼發我幫你看看,你有msn沒有?有的話加我antterminator@hotmail.com  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 15:45 螞蟻終結者

            @ktls
            email:antterminator@gmail.com
            msn:antterminator@hotmail.com
            這樣的話可能是其它的問題,那把abc.doc發給我測試下吧。
            這個本來是考慮跨平臺使用的,如果做成dll就只能windows用了。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 15:49 螞蟻終結者

            @ktls
            md5.update(ifstream("C:\\abc.doc"));
            剛才沒注意到,ifstream默認是以文本模式打開的,改成二進制應該就可以了:
            md5.update(ifstream("C:\\abc.doc", ios::binary));   回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 16:07 ktls

            是我自己沒看清楚,我看到FileDigest里已經是用二進制打開了,就沒仔細看后面調用的代碼,現在已經解決,非常感謝。  回復  更多評論   

            # re: MD5算法的C++實現 2008-10-09 16:10 螞蟻終結者

            @ktls
            不客氣,很多人用的時候都有這個問題,在這里弄清楚了免得后面的人再走彎路!  回復  更多評論   

            # re: MD5算法的C++實現 2009-01-07 16:41 far

            我想寫一個非標準的MD5算法,有哪些參數可以任意修改?
            比如ABCD的初始值,還是每次移位的位數?或者可以做更大的修改?
            能夠保證和標準MD5類似,沖突盡量小
              回復  更多評論   

            # re: MD5算法的C++實現 2009-01-08 13:15 螞蟻終結者

            @far
            其實最簡單方法就是修改ABCD的初始值,哪怕只是修改其中一位數,得到的md5值也會跟標準的完全不一樣。因為md5算法的整個過程都是以ABCD這4個數為基礎。  回復  更多評論   

            # re: MD5算法的C++實現 2009-01-09 10:14 hai

            看過了,收藏!
            牛人!頂下!  回復  更多評論   

            # re: MD5算法的C++實現 2009-01-29 15:27 roger

            很多地方都看到了這篇文章,只不過你這里多了個make文件。。。。
            請問樓主這里是原創么?
            謝謝  回復  更多評論   

            # re: MD5算法的C++實現 2009-02-02 09:07 螞蟻終結者

            我這里是原創呵呵,不過不知道你說的make文件是什么?我這里好像沒有  回復  更多評論   

            # re: MD5算法的C++實現[未登錄] 2009-02-13 10:04 Winter

            感謝 ant 的這個類, 其實已經用了好久了, 今天才來道謝 >.<
            額, 主要是想多問一個問題 - -!
            如果是包含亂碼的 unicode 路徑在用 ifstream 的時候該怎么做呢 @@
            之前 unicode 路徑都是 WideCharToMultiByte 然后調用類的...
            不過如果是帶亂碼的路徑換成 ANSI 就不行了
            3Q ^^  回復  更多評論   

            # re: MD5算法的C++實現[未登錄] 2009-02-13 10:18 Winter

            :P 大概要求高了點...
            如果想很好支持 UNICODE 亂碼路徑的話感覺整個類都需要改了
            剛才試了下 WinMD5 或 Hash 這兩個常用的校驗軟件
            發現也無法支持亂碼 (大概他們用的也是那個最老的標準 MD5 類吧 ^^)
            anyway, thx alot : )  回復  更多評論   

            # re: MD5算法的C++實現 2009-02-20 10:43 Nihlathak

            問主人一個問題啊:為什么以下代碼
            md5.reset();
            md5.update(ifstream("E:\\1.txt"));
            PrintMD5("E:\\1.txt", md5);
            當E盤不存在這個文件的時候也能出結果呢?
            不好意思我C++小白,就想請教一下  回復  更多評論   

            # re: MD5算法的C++實現 2009-02-20 12:40 螞蟻終結者

            @Nihlathak
            當文件不存在的時候得到的結果肯定是錯誤的。
            上面的例子寫成那樣只是為了演示用法。
            最好在調用update前判斷一下文件是否存在:
            md5.reset();
            ifstream file("E:\\1.txt");
            if (!file) {
            // error: can not open file
            }
            else {
            md5.update();
            PrintMD5("E:\\1.txt", md5);
            }
              回復  更多評論   

            # re: MD5算法的C++實現 2009-02-20 14:00 Nihlathak

            呵呵,謝了  回復  更多評論   

            # re: MD5算法的C++實現 2009-02-23 11:33 涼風

            你好我想問下 像加密后我要還原 那該怎么還原   回復  更多評論   

            # re: MD5算法的C++實現 2009-02-23 11:38 螞蟻終結者

            @涼風
            md5算法是一種hash算法,是單向的,還原是不可能的。因為多份數據可能計算出相同的md5值。  回復  更多評論   

            # re: MD5算法的C++實現 2009-02-23 19:54 roger

            引用你的code,需要收費么?收的話收多少?  回復  更多評論   

            # re: MD5算法的C++實現 2009-02-23 20:01 螞蟻終結者

            @roger
            呵呵,哥們說笑了,不收費,若是覺得不錯的話直接用就行了!  回復  更多評論   

            # re: MD5算法的C++實現 2009-02-26 19:40 roger

            多謝樓主。這要是在美國,說不定樓主就發財了。
            可以雇些律師,去告使用你code的人;)
              回復  更多評論   

            # re: MD5算法的C++實現 2009-03-07 07:19 chang

            我現在想在16bits系統中實現MD5,能給些建議嗎?還有,不調用update函數可以嗎?謝謝!  回復  更多評論   

            # re: MD5算法的C++實現 2009-03-07 11:56 螞蟻終結者

            @chang
            16位系統下應該可以拿上面的代碼移植,比如需要把md5.h中的
            typedef unsigned int uint32;
            改為
            typedef unsigned long uint32;
            可能還需要改動其他代碼,我這里沒有條件測試,你不妨測試一下。

            update是唯一的接口,不調用是不行的呵呵。  回復  更多評論   

            # re: MD5算法的C++實現 2009-04-05 17:12 anyangtao

            string str1 = "abcdefghijklmn";
            md5.update(str1);
            cout << md5.toString() << endl;
            cout << MD5("abcdefghijklmn").toString() << endl;
            string str2 = str1 ;
            md5.update(str2);
            cout << md5.toString() << endl;

            前兩個輸出的值相同,但第三個輸出和前兩個輸出的并不一樣,未找出原因,望指點。  回復  更多評論   

            # re: MD5算法的C++實現 2009-04-05 17:29 螞蟻終結者

            調用update是有累加效果的,上面的代碼:
            ...
            md5.update(str1);
            ...
            md5.update(str2);
            實際上得到的是"abcdefghijklmnabcdefghijklmn"的md5值

            如果想重復使用某個MD5對象,需要在下次update前先reset,如下:
            ...
            string str2 = str1 ;
            //這里加上reset
            md5.reset();
            md5.update(str2);
            ...
              回復  更多評論   

            # 鏈接變量的初始化問題 2009-04-08 01:22 csu_boy

            為什么用 _state[0] = 0x67452301;
            _state[1] = 0xefcdab89;
            _state[2] = 0x98badcfe;
            _state[3] = 0x10325476;
            這些值
            而不是網上說的
            _state[0] = 0x01234567;
            _state[1] = 0x89abcdef;
            _state[2] = 0xfedcba98;
            _state[3] = 0x76543210;
            我用下面的值算就對應不了標準的MD5值了  回復  更多評論   

            # re: MD5算法的C++實現 2009-04-08 11:52 螞蟻終結者

            @csu_boy
            這個是Endian的問題,本文中md5的實現是基于Little Endian的機器,所以要寫成下面這樣:
            _state[0] = 0x67452301;
            _state[1] = 0xefcdab89;
            _state[2] = 0x98badcfe;
            _state[3] = 0x10325476;
            如果是Big Endian的機器,則要寫成:
            _state[0] = 0x01234567;
            _state[1] = 0x89abcdef;
            _state[2] = 0xfedcba98;
            _state[3] = 0x76543210;
              回復  更多評論   

            # re: MD5算法的C++實現 2009-04-16 15:45 csu_boy

            據說MD5連文件的屬性改變了也會計算出不同的MD5值,是這么回事嗎?  回復  更多評論   

            # re: MD5算法的C++實現 2009-04-16 16:31 螞蟻終結者

            @csu_boy
            這個應該是跟計算md5值的軟件實現有關,一般來說都只看文件內容,內容相同的文件md5就是一樣的  回復  更多評論   

            # re: MD5算法的C++實現 2009-04-27 22:35 MM

            該程序怎樣修改可以實現對數字(例:ip包凈核)的認證呢?請指教!  回復  更多評論   

            # re: MD5算法的C++實現 2009-04-27 23:03 螞蟻終結者

            @MM
            你是要計算純數據的md5值?
            那可以用這個重載方法:
            void update(const void* input, size_t length);

            比如:
            1.計算一個int的md5值:
            int i = 12345;
            MD5 md;
            md.update(&i, sizeof(i));
            cout << md.toString() << endl;

            2.計算一個struct的md5值:
            struct Package {
            char buffer[32];
            int i;
            //...
            };

            Package pkg;
            MD5 md;
            md.update(&pkg, sizeof(pkg));
            cout << md.toString() << endl;

            不知道這是否是你想要的功能?  回復  更多評論   

            # re: MD5算法的C++實現 2009-04-30 11:16 adang

            螞蟻終結者,請問一下有沒有“test.txt”文件?可以的話,麻煩傳給我一份(還有加密后的結果)。我現在用的是QT版本的那個MD5算法,想驗證一下加密出來的結果是否和你們的一致,字符串的已經可以了,現在只剩下文件加密了。我的郵箱:adang322@126.com。謝謝!  回復  更多評論   

            # re: MD5算法的C++實現 2009-05-27 08:50 windcao

            我移植了一個到symbian上
            下載:http://download.csdn.net/source/1355073
            我的MSN: windcao@hotmail.com  回復  更多評論   

            # re: MD5算法的C++實現 2009-05-27 11:25 windcao

            http://download.csdn.net/source/1355214
            以這個為準,剛才那個有點別的問題編譯出錯。

              回復  更多評論   

            # re: MD5算法的C++實現 2009-06-09 15:36 lalalal

            非常感謝那位提醒64位的同學。。。  回復  更多評論   

            # re: MD5算法的C++實現 2009-08-29 16:56 nofree

            嗯,寫得不錯,不過那個大端小端的問題可以很容易實現嘛,干嘛用32位常量直接賦值呢?一個字節一個字節來賦值就ok了,我說的是下面這里:
            _state[0] = 0x67452301;
            _state[1] = 0xefcdab89;
            _state[2] = 0x98badcfe;
            _state[3] = 0x10325476;
              回復  更多評論   

            # re: MD5算法的C++實現 2009-09-07 23:55 summer

            謝謝!  回復  更多評論   

            # re: MD5算法的C++實現 2009-09-17 16:45 jaosnjee

            我發現有BUG  回復  更多評論   

            # 我發現有BUG 2009-09-17 16:51 jaosnjee

            根據WIKI百科的MD5介紹,他們給出了三個例子:
            一般128位的MD5散列被表示為32位十六進制數字。以下是一個43位長ASCII字母列的MD5散列:
            MD5("The quick brown fox jumps over the lazy dog")
            = 9e107d9d372bb6826bd81d3542a419d6
            即使在原文中作一個小變化(比如用c取代d)其散列也會發生巨大的變化:
            MD5("The quick brown fox jumps over the lazy cog")
            = 1055d3e698d289f2af8663725127bd4b
            空文的散列為:
            MD5("")
            = d41d8cd98f00b204e9800998ecf8427e
            為什么我在用你的程序驗證The quick brown fox jumps over the lazy dog得到了相同的結果,而把這句話中c取代d后卻得不到相同的結果?我之后又將c改回d,連續算兩變,居然得到不同的MD5值!!!  回復  更多評論   

            # 不好意思搞錯了,關于"我發現有BUG" 2009-09-17 17:01 jaosnjee

            沒有在兩次計算間插入
            md5.reset();
            不好意思,有點攪局了.
            樓主啊,你的參考代碼怎么也不在每次計算后都加上
            md5.reset();啊?害我瞎忙活
              回復  更多評論   

            # re: 不能下載 2010-01-07 16:20 光光兔

            不能下載啊.兄弟.
            只有Vrcats修改的Qt版本可以下載.

            看得我眼讒哦.呵呵.
            請幫我發到wcg_0321@163.com好嗎?  回復  更多評論   

            # re: 不能下載 2010-01-07 16:21 光光兔

            不能下載啊.兄弟.
            只有Vrcats修改的Qt版本可以下載.

            看得我眼讒哦.呵呵.
            請幫我發到wcg_0321@163.com好嗎?  回復  更多評論   

            # re: MD5算法的C++實現 2010-07-05 15:35 cll

            借用了,非常感謝。  回復  更多評論   

            # re: MD5算法的C++實現[未登錄] 2010-08-30 23:34 liu

            你好,看了你的介紹之后懂了不少,不過我比較笨還是有很多不懂,我的理解是這樣的:假如第一次update(str1),然后打印str1的md5,接著update(str2),這時str1的前strlen(str1)-strlen(str1)%64個字符應該不用再處理(transform)了吧,那么程序在哪里保存前面strlen(str1)-strlen(str1)%64個字符的transform結果的呢?  回復  更多評論   

            # re: MD5算法的C++實現[未登錄] 2010-08-31 21:53 liu

            唉,昨天沒仔細看,明明就有一個oldState.現在大體流程是看懂了,呵呵  回復  更多評論   

            # re: MD5算法的C++實現 2010-09-19 00:08 Wind

            螞蟻大哥,弱弱的請教下:T[i]是什么意思?你在md5.cpp中直接傳進去的一串16進制字符又代表什么意思?  回復  更多評論   

            # re: MD5算法的C++實現 2010-11-05 23:58 Tidus

            @Wind
            常數T[i]可以如下選擇:
            在第i步中,T[i]是4294967296*abs(sin(i))的整數部分,i的單位是弧度。
            可參考http://www.ietf.org/rfc/rfc1321.txt  回復  更多評論   

            # re: MD5算法的C++實現 2011-03-24 11:35 yun

            為什么把程序移植到MFC中就出現 錯誤
            Unhandled exception at 0x0002ded0 in .exe: 0xC0000005: Access violation.  回復  更多評論   

            # re: MD5算法的C++實現 2011-06-15 21:05 Tim

            學習~  回復  更多評論   

            # re: MD5算法的C++實現 2011-07-22 16:46 士大夫

            用這個計算文件好像不對  回復  更多評論   

            # re: MD5算法的C++實現 2011-07-25 11:40 馬燈

            @士大夫
            對的,注意打開方式,上面有帖子說明  回復  更多評論   

            # re: MD5算法的C++實現[未登錄] 2011-08-03 21:58 JAMES

            你好,如果要產生16位的MD5,該怎么辦
            求助
            ifdyo@hotmail.com  回復  更多評論   

            # re: MD5算法的C++實現 2011-08-25 10:34 IT

            你好,我想問一下 將輸入信息的原始長度b(bit)表示成一個64-bit的數字 這句話怎么理解,比如我輸入的是 "abcdefghijk", 怎么表示成一個64bit的數字 。。  回復  更多評論   

            # re: MD5算法的C++實現 2011-12-08 05:37 RiggsCaitlin34

            I think that to get the <a href="http://goodfinance-blog.com/topics/business-loans">business loans</a> from creditors you ought to present a firm motivation. However, one time I have got a short term loan, just because I wanted to buy a bike.   回復  更多評論   

            # re: MD5算法的C++實現 2012-01-12 15:57 aaa

            我發現對中文進行加密時結果不對,是不是有問題?  回復  更多評論   

            # re: MD5算法的C++實現 2012-03-15 10:21 常超

            著急用,先拿來啊。回頭再好好看看。  回復  更多評論   

            # re: MD5算法的C++實現 2012-03-22 18:18 wyk

            謝謝分享,下來看過,接口設計很好,學習  回復  更多評論   

            # re: MD5算法的C++實現 2012-04-11 17:50 sean

            謝謝分享,質量不錯的代碼。  回復  更多評論   

            # re: MD5算法的C++實現 2012-04-30 02:22 Comparatif forfait mobile

            你好,看了你的介紹之后懂了不少,不過我比較笨還是有很多不懂,我的理解是這樣的:假如第一次update(str1),然后打印str1的md5,接著update(str2),這時str1的前strlen(str1)-strlen(str1)%64個字符應該不用再處理(transform)了吧,那么程序在哪里保存前面strlen(str1)-strlen(str1)%64個字符的transform結果的呢? 回復 更多評論   回復  更多評論   

            # re: MD5算法的C++實現 2012-05-02 11:17 狂奔的蝸牛

            @光光兔
            您好!能給我發一份Vrcats修改的Qt版本嗎?麻煩您了,謝謝!!!急需~~~我的QQ:690905539
              回復  更多評論   

            # re: MD5算法的C++實現 2012-05-02 11:20 狂奔的蝸牛

            @VrcatS
            您好:能給我發一份嗎? 我的QQ:690905539 謝謝~~~急需  回復  更多評論   

            # re: MD5算法的C++實現 2012-08-20 21:53 aking

            學習了!很多地方看不太懂,收藏起來了。實在看不懂就直接用啦!  回復  更多評論   

            # re: MD5算法的C++實現 2012-09-04 15:19 xwj

            同樣一個文件,中文路徑和英文路徑計算出來的md5碼不一樣。

            中文路徑下,所有的文件計算出來的md5碼都一樣,

            英文路徑下沒問題。

            請指點,32581991@qq.com  回復  更多評論   

            # re: MD5算法的C++實現 2012-10-23 21:13 WWE

            為什么
            md5.update("bc");
            PrintMD5("abc", md5);
            不需要reset
            而后面
            md5.reset();
            md5.update("message digest");
            PrintMD5("message digest", md5);
            需要呢?  回復  更多評論   

            # re: MD5算法的C++實現 2013-11-07 20:55 Dan

            想請問一下,那個我該怎么在主函數中調用MD5算法  回復  更多評論   

            # re: MD5算法的C++實現 2014-05-13 19:51 snoopy

            你好,我想請問一下,對于字節串如何按512位分塊,需要先轉化為對應的二進制編碼嗎  回復  更多評論   

            # re: MD5算法的C++實現 2014-11-29 01:47 KomeijiKuroko

            建議在md5.h的聲明部分,
            MD5(ifstream& in);
            加上explicit,

            #Md5.h line 20
            explicit MD5(ifstream& in);

            要不然 MD5(ifstream("File")) 時候,IntelliSense總是把 ifstream("File")看成到MD5的隱式轉換,和

            #md5.h line 37
            private:
            MD5(const MD5&);

            矛盾  回復  更多評論   

            評論共2頁: 1 2 
            国产aⅴ激情无码久久| 久久精品99久久香蕉国产色戒| 91久久精品视频| 亚洲精品乱码久久久久久不卡| 伊人久久大香线蕉亚洲五月天| 久久99热狠狠色精品一区| 久久国产精品免费| 色欲久久久天天天综合网精品| 51久久夜色精品国产| 久久狠狠爱亚洲综合影院| 99久久国产主播综合精品| 狠狠综合久久综合88亚洲| 久久996热精品xxxx| 精品九九久久国内精品| 久久久国产视频| 国产ww久久久久久久久久| 无码AV中文字幕久久专区| 久久国产精品偷99| 999久久久无码国产精品| 精品久久亚洲中文无码| 久久久久无码专区亚洲av| 久久国产精品一国产精品金尊| 伊人久久亚洲综合影院| 国产2021久久精品| 国产99精品久久| 伊人色综合久久天天人手人婷 | 久久久黄色大片| 97久久精品人人做人人爽| 久久综合精品国产二区无码| 午夜精品久久久久久影视777 | 激情五月综合综合久久69| 精品国产乱码久久久久久郑州公司| 亚洲精品无码久久久| 久久精品国产一区二区三区| 国产激情久久久久影院| 国产精品久久久99| 99热精品久久只有精品| 国产免费久久精品丫丫| 大美女久久久久久j久久| 国产精品伦理久久久久久 | 无码任你躁久久久久久老妇App|