• <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>
            隨筆 - 505  文章 - 1034  trackbacks - 0
            <2008年12月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910


            子曾經曰過:編程無他,唯手熟爾!

            常用鏈接

            留言簿(94)

            隨筆分類(649)

            隨筆檔案(505)

            相冊

            BCB

            Crytek

            • crymod
            • Crytek's Offical Modding Portal

            Game Industry

            OGRE

            other

            Programmers

            Qt

            WOW Stuff

            搜索

            •  

            積分與排名

            • 積分 - 911346
            • 排名 - 14

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜


            一、理論部分:
            1、預備知識
            1.1什么是數據校驗
            通俗的說,就是為保證數據的完整性,用一種指定的算法對原始數據計算出的一個校驗值。接收方用同樣的算法計算一次校驗值,如果和隨數據提供的校驗值一樣,就說明數據是完整的。
            1.2最簡單的檢驗
            實現方法:最簡單的校驗就是把原始數據和待比較數據直接進行比較,看是否完全一樣這種方法是最安全最準確的。同時也是效率最低的。
            適用范圍:簡單的數據量極小的通訊
            應用例子:龍珠cpu在線調試工具bbug.exe。它和龍珠cpu間通訊時,bbug發送一個字節cpu返回收到的字節,bbug確認是剛才發送字節后才繼續發送下一個字節的。
            1.3奇偶校驗Parity Check
            實現方法:在數據存儲和傳輸中,字節中額外增加一個比特位,用來檢驗錯誤。校驗位可以通過數據位異或計算出來。
            應用例子:單片機串口通訊有一模式就是8位數據通訊,另加第9位用于放校驗值。
            1.4 bcc異或校驗法(block check character)
            實現方法:很多基于串口的通訊都用這種既簡單又相當準確的方法。它就是把所有數據都和一個指定的初始值(通常是0)異或一次,最后的結果就是校驗值,通常
            把她附在通訊數據的最后一起發送出去。接收方收到數據后自己也計算一次異或和校驗值,如果和收到的校驗值一致就說明收到的數據是完整的。
            校驗值計算的代碼類似于:
            unsigned uCRC=0;//校驗初始值
            for(int i=0;i<DataLenth;i++) uCRC^=Data[i];
            適用范圍:適用于大多數要求不高的數據通訊。
            應用例子:ic卡接口通訊、很多單片機系統的串口通訊都使用。
            1.5 crc循環冗余校驗(Cyclic Redundancy Check)
            實現方法:這是利用除法及余數的原理來進行錯誤檢測的.將接收到的碼組進行除法運算
            ,如果除盡,則說明傳輸無誤;如果未除盡,則表明傳輸出現差錯。crc校驗
            具還有自動糾錯能力。
            crc檢驗主要有計算法和查表法兩種方法,網上很多實現代碼。
            適用范圍:CRC-12碼通常用來傳送6-bit字符串;CRC-16及CRC-CCITT碼則用是來傳送
            8-bit字符。CRC-32:硬盤數據,網絡傳輸等
            應用例子:rar,以太網卡芯片、MPEG解碼芯片中
            1.6 md5校驗和數字簽名
            實現方法:主要有md5和des算法。
            適用范圍:數據比較大或要求比較高的場合。如md5用于大量數據、文件校驗,des用于保密數據的校驗(數字簽名)等等。
            應用例子:文件校驗、銀行系統的交易數據
            2、具體的實現理論
            2.1 算法概述
            MD5算法是MD4算法的改進算法。Ron Rivest 于1990年提出MD4單向散列函數,MD表示消息摘要(Message Digest),對輸入消息,算法產生128位散列值。該算法首次公布之后,Bert den Boer和Antoon Bosselaers 對算法三輪中的后兩輪進行了成功的密碼分析。在一個不相關的分析結果中,Ralph MerKle成功地攻擊了前兩輪。盡管這些攻擊都沒有擴展到整個算法,但Rivest還是改進了其算法,結果就是MD5算法。
            MD5算法是MD4的改進算法,它比MD4更復雜,但設計思想相似,輸入的消息可任意長,輸出結果也仍為128位,特別適用于高速軟件實現,是基于32-位操作數的一些簡單的位操作。
            2.2 算法步驟
            l 將輸入消息按512-位分組,最后要填充成為512位的整數倍,且最后一組的后64位用來填充消息長度(填充前)。填充方法為附一個1在消息后,后接所要求的多個0。這樣可以確保不同消息在填充后不相同。
            l 由于留出64位用來表示消息長度,那么消息的長度最多可達264字節,相當于4G×4G字節,文件的長度是不可能達到這么大,因此通常都是只采用64位中的低32位來表示消息長度,高32位填充0。
            l 初始化MD變量。由于每輪輸出128位,這128位可用下面四個32位字A,B,C,D來表示。其初始值設為:
            A=0x01234567
            B=0x89ABCDEF
            C=0xFEDCBA98
            D=0x76543210
            l 開始進入算法主循環,循環的次數是消息中512位消息分組的數目。先將上面A、B、C、D四個變量分別復制到另外四個變量a、b、c、d中去。主循環有四輪,每輪很相似。每輪進行16次操作,每次操作對a、b、c、d四個變量中的三個作一次非線性函數運算,然后將所得結果加上第四個變量,消息的一個子分組和一個常數。再將所得結果向右環移一個不定的數,并加上a,b,c或d中之一。最后用該結果取代a,b,c或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的對應位是獨立和均勻的,那么結果的每一位也應是獨立和均勻的。函數F是按逐位方式操作:如果X,那么Y,否則Z。函數H是逐位奇偶操作符。
            設Mj表示消息的第j個子分組(從0到15),<<<s表示循環左移s,則四種操作為:
            FF(a,b,c,d,Mj,s,ti)表示a = b+((a+F(b,c,d)+ Mj + ti)<<<s)
            GG(a,b,c,d,Mj,s,ti)表示a = b+((a+G(b,c,d)+ Mj + ti)<<<s)
            HH(a,b,c,d,Mj,s,ti)表示a = b+((a+H(b,c,d)+ Mj + ti)<<<s)
            II(a,b,c,d,Mj,s,ti)表示a = b+((a+I(b,c,d)+ Mj + ti)<<<s)
            四輪(64步)結果略。
            注:常數ti的選擇:
            第i步中,ti是232 ×abs (sin(i))的整數部分,i的單位是弧度。
            所有這些完成之后,將A,B,C,D分別加上a,b,c,d。然后用下一分組數據繼續運行算法,最后的輸出是A,B,C和D的級聯。
            l 最后得到的A,B,C,D就是輸出結果,A是低位,D為高位,DCBA組成128位輸出結果。
            2.3 MD5的安全性
            Ron Rivest概述了MD5安全性[8]:
            l 與MD4相比,增加了第四輪。
            l 每一步均有唯一的加法常數。
            l 為減弱第二輪中函數G的對稱性從((X∧Y) ∨(X∧Z) ∨(Y∧Z))變為((X∧Z) ∨(Y∧( Z)))。
            l 每一步加上了上一步的結果,引起更快的雪崩效應。
            l 改變了第二輪和第三輪中訪問消息子分組的次序,使其形式更不相似。
            l 近似優化了每一輪中的循環左移位移量以實現更快的雪崩效應。各輪的位移量互不相同。
            從安全角度講,MD5的輸出為128位,若采用純強力攻擊尋找一個消息具有給定Hash值的計算困難性為2128,用每秒可試驗1 000 000 000個消息的計算機需時1.07×1022年。若采用生日攻擊法,尋找有相同Hash值的兩個消息需要試驗264個消息,用每秒可試驗1 000 000 000個消息的計算機需時585年。

            二、實現方法
            由于此處的文件校驗用到要求比較高的場合,故采用了方法6,md5校驗算法,從CodeGuru下載了一個md5校驗算法的實現模塊,加入自己要校驗的文件名,實現完成。下面具體描述一下實現過程:
            1、創建一個簡單的對話框程序;
            2、設置CString類型的變量m_filename和m_strFileChecksum以存放要校驗的文件名和校驗和;
            3、在對話框類中創建ChecksumSelectedFile()函數,調用md5校驗和類(附錄中有其實現文件)中的GetMD5計算文件校驗和。
            4、使用定時器定時巡檢該文件的校驗和,一旦發現校驗和發生變化,立刻出現提示。
            三、附錄(md5算法實現的源碼)
            以下代碼實現均來自www.codeguru.com。
            1、MD5ChecksumDefines.h(定義相關常量的頭文件)
            //Magic initialization constants
            #define MD5_INIT_STATE_0 0x67452301
            #define MD5_INIT_STATE_1 0xefcdab89
            #define MD5_INIT_STATE_2 0x98badcfe
            #define MD5_INIT_STATE_3 0x10325476

            //Constants for Transform routine.
            #define MD5_S11  7
            #define MD5_S12 12
            #define MD5_S13 17
            #define MD5_S14 22
            #define MD5_S21  5
            #define MD5_S22  9
            #define MD5_S23 14
            #define MD5_S24 20
            #define MD5_S31  4
            #define MD5_S32 11
            #define MD5_S33 16
            #define MD5_S34 23
            #define MD5_S41  6
            #define MD5_S42 10
            #define MD5_S43 15
            #define MD5_S44 21

            //Transformation Constants - Round 1
            #define MD5_T01  0xd76aa478 //Transformation Constant 1 
            #define MD5_T02  0xe8c7b756 //Transformation Constant 2
            #define MD5_T03  0x242070db //Transformation Constant 3
            #define MD5_T04  0xc1bdceee //Transformation Constant 4
            #define MD5_T05  0xf57c0faf //Transformation Constant 5
            #define MD5_T06  0x4787c62a //Transformation Constant 6
            #define MD5_T07  0xa8304613 //Transformation Constant 7
            #define MD5_T08  0xfd469501 //Transformation Constant 8
            #define MD5_T09  0x698098d8 //Transformation Constant 9
            #define MD5_T10  0x8b44f7af //Transformation Constant 10
            #define MD5_T11  0xffff5bb1 //Transformation Constant 11
            #define MD5_T12  0x895cd7be //Transformation Constant 12
            #define MD5_T13  0x6b901122 //Transformation Constant 13
            #define MD5_T14  0xfd987193 //Transformation Constant 14
            #define MD5_T15  0xa679438e //Transformation Constant 15
            #define MD5_T16  0x49b40821 //Transformation Constant 16

            //Transformation Constants - Round 2
            #define MD5_T17  0xf61e2562 //Transformation Constant 17
            #define MD5_T18  0xc040b340 //Transformation Constant 18
            #define MD5_T19  0x265e5a51 //Transformation Constant 19
            #define MD5_T20  0xe9b6c7aa //Transformation Constant 20
            #define MD5_T21  0xd62f105d //Transformation Constant 21
            #define MD5_T22  0x02441453 //Transformation Constant 22
            #define MD5_T23  0xd8a1e681 //Transformation Constant 23
            #define MD5_T24  0xe7d3fbc8 //Transformation Constant 24
            #define MD5_T25  0x21e1cde6 //Transformation Constant 25
            #define MD5_T26  0xc33707d6 //Transformation Constant 26
            #define MD5_T27  0xf4d50d87 //Transformation Constant 27
            #define MD5_T28  0x455a14ed //Transformation Constant 28
            #define MD5_T29  0xa9e3e905 //Transformation Constant 29
            #define MD5_T30  0xfcefa3f8 //Transformation Constant 30
            #define MD5_T31  0x676f02d9 //Transformation Constant 31
            #define MD5_T32  0x8d2a4c8a //Transformation Constant 32

            //Transformation Constants - Round 3
            #define MD5_T33  0xfffa3942 //Transformation Constant 33
            #define MD5_T34  0x8771f681 //Transformation Constant 34
            #define MD5_T35  0x6d9d6122 //Transformation Constant 35
            #define MD5_T36  0xfde5380c //Transformation Constant 36
            #define MD5_T37  0xa4beea44 //Transformation Constant 37
            #define MD5_T38  0x4bdecfa9 //Transformation Constant 38
            #define MD5_T39  0xf6bb4b60 //Transformation Constant 39
            #define MD5_T40  0xbebfbc70 //Transformation Constant 40
            #define MD5_T41  0x289b7ec6 //Transformation Constant 41
            #define MD5_T42  0xeaa127fa //Transformation Constant 42
            #define MD5_T43  0xd4ef3085 //Transformation Constant 43
            #define MD5_T44  0x04881d05 //Transformation Constant 44
            #define MD5_T45  0xd9d4d039 //Transformation Constant 45
            #define MD5_T46  0xe6db99e5 //Transformation Constant 46
            #define MD5_T47  0x1fa27cf8 //Transformation Constant 47
            #define MD5_T48  0xc4ac5665 //Transformation Constant 48

            //Transformation Constants - Round 4
            #define MD5_T49  0xf4292244 //Transformation Constant 49
            #define MD5_T50  0x432aff97 //Transformation Constant 50
            #define MD5_T51  0xab9423a7 //Transformation Constant 51
            #define MD5_T52  0xfc93a039 //Transformation Constant 52
            #define MD5_T53  0x655b59c3 //Transformation Constant 53
            #define MD5_T54  0x8f0ccc92 //Transformation Constant 54
            #define MD5_T55  0xffeff47d //Transformation Constant 55
            #define MD5_T56  0x85845dd1 //Transformation Constant 56
            #define MD5_T57  0x6fa87e4f //Transformation Constant 57
            #define MD5_T58  0xfe2ce6e0 //Transformation Constant 58
            #define MD5_T59  0xa3014314 //Transformation Constant 59
            #define MD5_T60  0x4e0811a1 //Transformation Constant 60
            #define MD5_T61  0xf7537e82 //Transformation Constant 61
            #define MD5_T62  0xbd3af235 //Transformation Constant 62
            #define MD5_T63  0x2ad7d2bb //Transformation Constant 63
            #define MD5_T64  0xeb86d391 //Transformation Constant 64


            //Null data (except for first BYTE) used to finalise the checksum calculation
            static unsigned char PADDING[64= {
              
            0x80000000000000000000000,
              
            00000000000000000000000,
              
            0000000000000000000
            };

            2、CountChecksum.h(md5校驗和類的頭文件)
            class CMD5Checksum  
            {
            public:
            //interface functions for the RSA MD5 calculation
            static CString GetMD5(BYTE* pBuf, UINT nLength);
            static CString GetMD5(CFile& File);
            static CString GetMD5(const CString& strFilePath);

            protected:
            //constructor/destructor
            CMD5Checksum();
            virtual ~CMD5Checksum() {};

            //RSA MD5 implementation
            void Transform(BYTE Block[64]);
            void Update(BYTE* Input, ULONG nInputLen);
            CString Final();
            inline DWORD RotateLeft(DWORD x, 
            int n);
            inline 
            void FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
            inline 
            void GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
            inline 
            void HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
            inline 
            void II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);

            //utility functions
            void DWordToByte(BYTE* Output, DWORD* Input, UINT nLength);
            void ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength);

            private:
            BYTE  m_lpszBuffer[
            64];  //input buffer
            ULONG m_nCount[2];   //number of bits, modulo 2^64 (lsb first)
            ULONG m_lMD5[4];   //MD5 checksum
            };

            #endif // !defined(AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_)

            3、CountChecksum.cpp (md5校驗和類的實現文件)
            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::GetMD5
            DETAILS:  static, public
            DESCRIPTION: Gets the MD5 checksum for a specified file
            RETURNS:  CString : the hexadecimal MD5 checksum for the specified file
            ARGUMENTS:  CString& strFilePath : the full pathname of the specified file
            NOTES:   Provides an interface to the CMD5Checksum class. ''strFilePath'' name should 
                hold the full pathname of the file, eg C:\My Documents\Arcticle.txt.
                NB. If any problems occur with opening or reading this file, a CFileException
                will be thrown; callers of this function should be ready to catch this 
                exception.
            ****************************************************************************************
            */
            CString CMD5Checksum::GetMD5(
            const CString& strFilePath)
            {
            //open the file as a binary file in readonly mode, denying write access 
            CFile File(strFilePath, CFile::shareDenyNone);
            //the file has been successfully opened, so now get and return its checksum
            return GetMD5(File);
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::GetMD5
            DETAILS:  static, public
            DESCRIPTION: Gets the MD5 checksum for a specified file
            RETURNS:  CString : the hexadecimal MD5 checksum for the specified file
            ARGUMENTS:  CFile& File : the specified file
            NOTES:   Provides an interface to the CMD5Checksum class. ''File'' should be open in 
                binary readonly mode before calling this function. 
                NB. Callers of this function should be ready to catch any CFileException
                thrown by the CFile functions
            ****************************************************************************************
            */
            CString CMD5Checksum::GetMD5(CFile
            & File)
            {
            try
            {
              CMD5Checksum MD5Checksum;  
            //checksum object 
              int nLength = 0;    //number of bytes read from the file
              const int nBufferSize = 1024//checksum the file in blocks of 1024 bytes
              BYTE Buffer[nBufferSize];  //buffer for data read from the file

              
            //checksum the file in blocks of 1024 bytes
              while ((nLength = File.Read( Buffer, nBufferSize )) > 0 )
              {
               MD5Checksum.Update( Buffer, nLength );
              }

              
            //finalise the checksum and return it
              return MD5Checksum.Final();
            }

            //report any file exceptions in debug mode only
            catch (CFileException* e )
            {
              TRACE0(
            "CMD5Checksum::GetMD5: CFileException caught"); 
              
            throw e;
            }
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::GetMD5
            DETAILS:  static, public
            DESCRIPTION: Gets the MD5 checksum for data in a BYTE array
            RETURNS:  CString : the hexadecimal MD5 checksum for the specified data
            ARGUMENTS:  BYTE* pBuf  : pointer to the BYTE array
                UINT nLength : number of BYTEs of data to be checksumed
            NOTES:   Provides an interface to the CMD5Checksum class. Any data that can
                be cast to a BYTE array of known length can be checksummed by this
                function. Typically, CString and char arrays will be checksumed, 
                although this function can be used to check the integrity of any BYTE array. 
                A buffer of zero length can be checksummed; all buffers of zero length 
                will return the same checksum. 
            ****************************************************************************************
            */
            CString CMD5Checksum::GetMD5(BYTE
            * pBuf, UINT nLength)
            {
            //entry invariants
            AfxIsValidAddress(pBuf,nLength,FALSE);

            //calculate and return the checksum
            CMD5Checksum MD5Checksum;
            MD5Checksum.Update( pBuf, nLength );
            return MD5Checksum.Final();
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::RotateLeft
            DETAILS:  private
            DESCRIPTION: Rotates the bits in a 32 bit DWORD left by a specified amount
            RETURNS:  The rotated DWORD 
            ARGUMENTS:  DWORD x : the value to be rotated
                int n   : the number of bits to rotate by
            ****************************************************************************************
            */
            DWORD CMD5Checksum::RotateLeft(DWORD x, 
            int n)
            {
            //check that DWORD is 4 bytes long - true in Visual C++ 6 and 32 bit Windows
            ASSERT( sizeof(x) == 4 );

            //rotate and return x
            return (x << n) | (x >> (32-n));
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::FF
            DETAILS:  protected
            DESCRIPTION: Implementation of basic MD5 transformation algorithm
            RETURNS:  none
            ARGUMENTS:  DWORD &A, B, C, D : Current (partial) checksum
                DWORD X           : Input data
                DWORD S     : MD5_SXX Transformation constant
                DWORD T     : MD5_TXX Transformation constant
            NOTES:   None
            ****************************************************************************************
            */
            void CMD5Checksum::FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
            {
            DWORD F 
            = (B & C) | (~& D);
            += F + X + T;
            = RotateLeft(A, S);
            += B;
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::GG
            DETAILS:  protected
            DESCRIPTION: Implementation of basic MD5 transformation algorithm
            RETURNS:  none
            ARGUMENTS:  DWORD &A, B, C, D : Current (partial) checksum
                DWORD X           : Input data
                DWORD S     : MD5_SXX Transformation constant
                DWORD T     : MD5_TXX Transformation constant
            NOTES:   None
            ****************************************************************************************
            */
            void CMD5Checksum::GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
            {
            DWORD G 
            = (B & D) | (C & ~D);
            += G + X + T;
            = RotateLeft(A, S);
            += B;
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::HH
            DETAILS:  protected
            DESCRIPTION: Implementation of basic MD5 transformation algorithm
            RETURNS:  none
            ARGUMENTS:  DWORD &A, B, C, D : Current (partial) checksum
                DWORD X           : Input data
                DWORD S     : MD5_SXX Transformation constant
                DWORD T     : MD5_TXX Transformation constant
            NOTES:   None
            ****************************************************************************************
            */
            void CMD5Checksum::HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
            {
            DWORD H 
            = (B ^ C ^ D);
            += H + X + T;
            = RotateLeft(A, S);
            += B;
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::II
            DETAILS:  protected
            DESCRIPTION: Implementation of basic MD5 transformation algorithm
            RETURNS:  none
            ARGUMENTS:  DWORD &A, B, C, D : Current (partial) checksum
                DWORD X           : Input data
                DWORD S     : MD5_SXX Transformation constant
                DWORD T     : MD5_TXX Transformation constant
            NOTES:   None
            ****************************************************************************************
            */
            void CMD5Checksum::II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
            {
            DWORD I 
            = (C ^ (B | ~D));
            += I + X + T;
            = RotateLeft(A, S);
            += B;
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::ByteToDWord
            DETAILS:  private
            DESCRIPTION: Transfers the data in an 8 bit array to a 32 bit array
            RETURNS:  void
            ARGUMENTS:  DWORD* Output : the 32 bit (unsigned long) destination array 
                BYTE* Input   : the 8 bit (unsigned char) source array
                UINT nLength  : the number of 8 bit data items in the source array
            NOTES:   Four BYTES from the input array are transferred to each DWORD entry
                of the output array. The first BYTE is transferred to the bits (0-7) 
                of the output DWORD, the second BYTE to bits 8-15 etc. 
                The algorithm assumes that the input array is a multiple of 4 bytes long
                so that there is a perfect fit into the array of 32 bit words.
            ****************************************************************************************
            */
            void CMD5Checksum::ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength)
            {
            //entry invariants
            ASSERT( nLength % 4 == 0 );
            ASSERT( AfxIsValidAddress(Output, nLength
            /4, TRUE) );
            ASSERT( AfxIsValidAddress(Input, nLength, FALSE) );

            //initialisations
            UINT i=0//index to Output array
            UINT j=0//index to Input array

            //transfer the data by shifting and copying
            for ( ; j < nLength; i++, j += 4)
            {
              Output[i] 
            = (ULONG)Input[j]   | 
                 (ULONG)Input[j
            +1<< 8 | 
                 (ULONG)Input[j
            +2<< 16 | 
                 (ULONG)Input[j
            +3<< 24;
            }
            }

            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::Transform
            DETAILS:  protected
            DESCRIPTION: MD5 basic transformation algorithm;  transforms ''m_lMD5''
            RETURNS:  void
            ARGUMENTS:  BYTE Block[64]
            NOTES:   An MD5 checksum is calculated by four rounds of ''Transformation''.
                The MD5 checksum currently held in m_lMD5 is merged by the 
                transformation process with data passed in ''Block''.  
            ****************************************************************************************
            */
            void CMD5Checksum::Transform(BYTE Block[64])
            {
            //initialise local data with current checksum
            ULONG a = m_lMD5[0];
            ULONG b 
            = m_lMD5[1];
            ULONG c 
            = m_lMD5[2];
            ULONG d 
            = m_lMD5[3];

            //copy BYTES from input ''Block'' to an array of ULONGS ''X''
            ULONG X[16];
            ByteToDWord( X, Block, 
            64 );

            //Perform Round 1 of the transformation
            FF (a, b, c, d, X[ 0], MD5_S11, MD5_T01); 
            FF (d, a, b, c, X[ 
            1], MD5_S12, MD5_T02); 
            FF (c, d, a, b, X[ 
            2], MD5_S13, MD5_T03); 
            FF (b, c, d, a, X[ 
            3], MD5_S14, MD5_T04); 
            FF (a, b, c, d, X[ 
            4], MD5_S11, MD5_T05); 
            FF (d, a, b, c, X[ 
            5], MD5_S12, MD5_T06); 
            FF (c, d, a, b, X[ 
            6], MD5_S13, MD5_T07); 
            FF (b, c, d, a, X[ 
            7], MD5_S14, MD5_T08); 
            FF (a, b, c, d, X[ 
            8], MD5_S11, MD5_T09); 
            FF (d, a, b, c, X[ 
            9], MD5_S12, MD5_T10); 
            FF (c, d, a, b, X[
            10], MD5_S13, MD5_T11); 
            FF (b, c, d, a, X[
            11], MD5_S14, MD5_T12); 
            FF (a, b, c, d, X[
            12], MD5_S11, MD5_T13); 
            FF (d, a, b, c, X[
            13], MD5_S12, MD5_T14); 
            FF (c, d, a, b, X[
            14], MD5_S13, MD5_T15); 
            FF (b, c, d, a, X[
            15], MD5_S14, MD5_T16); 

            //Perform Round 2 of the transformation
            GG (a, b, c, d, X[ 1], MD5_S21, MD5_T17); 
            GG (d, a, b, c, X[ 
            6], MD5_S22, MD5_T18); 
            GG (c, d, a, b, X[
            11], MD5_S23, MD5_T19); 
            GG (b, c, d, a, X[ 
            0], MD5_S24, MD5_T20); 
            GG (a, b, c, d, X[ 
            5], MD5_S21, MD5_T21); 
            GG (d, a, b, c, X[
            10], MD5_S22, MD5_T22); 
            GG (c, d, a, b, X[
            15], MD5_S23, MD5_T23); 
            GG (b, c, d, a, X[ 
            4], MD5_S24, MD5_T24); 
            GG (a, b, c, d, X[ 
            9], MD5_S21, MD5_T25); 
            GG (d, a, b, c, X[
            14], MD5_S22, MD5_T26); 
            GG (c, d, a, b, X[ 
            3], MD5_S23, MD5_T27); 
            GG (b, c, d, a, X[ 
            8], MD5_S24, MD5_T28); 
            GG (a, b, c, d, X[
            13], MD5_S21, MD5_T29); 
            GG (d, a, b, c, X[ 
            2], MD5_S22, MD5_T30); 
            GG (c, d, a, b, X[ 
            7], MD5_S23, MD5_T31); 
            GG (b, c, d, a, X[
            12], MD5_S24, MD5_T32); 

            //Perform Round 3 of the transformation
            HH (a, b, c, d, X[ 5], MD5_S31, MD5_T33); 
            HH (d, a, b, c, X[ 
            8], MD5_S32, MD5_T34); 
            HH (c, d, a, b, X[
            11], MD5_S33, MD5_T35); 
            HH (b, c, d, a, X[
            14], MD5_S34, MD5_T36); 
            HH (a, b, c, d, X[ 
            1], MD5_S31, MD5_T37); 
            HH (d, a, b, c, X[ 
            4], MD5_S32, MD5_T38); 
            HH (c, d, a, b, X[ 
            7], MD5_S33, MD5_T39); 
            HH (b, c, d, a, X[
            10], MD5_S34, MD5_T40); 
            HH (a, b, c, d, X[
            13], MD5_S31, MD5_T41); 
            HH (d, a, b, c, X[ 
            0], MD5_S32, MD5_T42); 
            HH (c, d, a, b, X[ 
            3], MD5_S33, MD5_T43); 
            HH (b, c, d, a, X[ 
            6], MD5_S34, MD5_T44); 
            HH (a, b, c, d, X[ 
            9], MD5_S31, MD5_T45); 
            HH (d, a, b, c, X[
            12], MD5_S32, MD5_T46); 
            HH (c, d, a, b, X[
            15], MD5_S33, MD5_T47); 
            HH (b, c, d, a, X[ 
            2], MD5_S34, MD5_T48); 

            //Perform Round 4 of the transformation
            II (a, b, c, d, X[ 0], MD5_S41, MD5_T49); 
            II (d, a, b, c, X[ 
            7], MD5_S42, MD5_T50); 
            II (c, d, a, b, X[
            14], MD5_S43, MD5_T51); 
            II (b, c, d, a, X[ 
            5], MD5_S44, MD5_T52); 
            II (a, b, c, d, X[
            12], MD5_S41, MD5_T53); 
            II (d, a, b, c, X[ 
            3], MD5_S42, MD5_T54); 
            II (c, d, a, b, X[
            10], MD5_S43, MD5_T55); 
            II (b, c, d, a, X[ 
            1], MD5_S44, MD5_T56); 
            II (a, b, c, d, X[ 
            8], MD5_S41, MD5_T57); 
            II (d, a, b, c, X[
            15], MD5_S42, MD5_T58); 
            II (c, d, a, b, X[ 
            6], MD5_S43, MD5_T59); 
            II (b, c, d, a, X[
            13], MD5_S44, MD5_T60); 
            II (a, b, c, d, X[ 
            4], MD5_S41, MD5_T61); 
            II (d, a, b, c, X[
            11], MD5_S42, MD5_T62); 
            II (c, d, a, b, X[ 
            2], MD5_S43, MD5_T63); 
            II (b, c, d, a, X[ 
            9], MD5_S44, MD5_T64); 

            //add the transformed values to the current checksum
            m_lMD5[0+= a;
            m_lMD5[
            1+= b;
            m_lMD5[
            2+= c;
            m_lMD5[
            3+= d;
            }


            /*****************************************************************************************
            CONSTRUCTOR: CMD5Checksum
            DESCRIPTION: Initialises member data
            ARGUMENTS:  None
            NOTES:   None
            ****************************************************************************************
            */
            CMD5Checksum::CMD5Checksum()
            {
            // zero members
            memset( m_lpszBuffer, 064 );
            m_nCount[
            0= m_nCount[1= 0;

            // Load magic state initialization constants
            m_lMD5[0= MD5_INIT_STATE_0;
            m_lMD5[
            1= MD5_INIT_STATE_1;
            m_lMD5[
            2= MD5_INIT_STATE_2;
            m_lMD5[
            3= MD5_INIT_STATE_3;
            }

            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::DWordToByte
            DETAILS:  private
            DESCRIPTION: Transfers the data in an 32 bit array to a 8 bit array
            RETURNS:  void
            ARGUMENTS:  BYTE* Output  : the 8 bit destination array 
                DWORD* Input  : the 32 bit source array
                UINT nLength  : the number of 8 bit data items in the source array
            NOTES:   One DWORD from the input array is transferred into four BYTES 
                in the output array. The first (0-7) bits of the first DWORD are 
                transferred to the first output BYTE, bits bits 8-15 are transferred from
                the second BYTE etc. 
                
                The algorithm assumes that the output array is a multiple of 4 bytes long
                so that there is a perfect fit of 8 bit BYTES into the 32 bit DWORDs.
            ****************************************************************************************
            */
            void CMD5Checksum::DWordToByte(BYTE* Output, DWORD* Input, UINT nLength )
            {
            //entry invariants
            ASSERT( nLength % 4 == 0 );
            ASSERT( AfxIsValidAddress(Output, nLength, TRUE) );
            ASSERT( AfxIsValidAddress(Input, nLength
            /4, FALSE) );

            //transfer the data by shifting and copying
            UINT i = 0;
            UINT j 
            = 0;
            for ( ; j < nLength; i++, j += 4
            {
              Output[j] 
            =   (UCHAR)(Input[i] & 0xff);
              Output[j
            +1= (UCHAR)((Input[i] >> 8& 0xff);
              Output[j
            +2= (UCHAR)((Input[i] >> 16& 0xff);
              Output[j
            +3= (UCHAR)((Input[i] >> 24& 0xff);
            }
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::Final
            DETAILS:  protected
            DESCRIPTION: Implementation of main MD5 checksum algorithm; ends the checksum calculation.
            RETURNS:  CString : the final hexadecimal MD5 checksum result 
            ARGUMENTS:  None
            NOTES:   Performs the final MD5 checksum calculation (''Update'' does most of the work,
                this function just finishes the calculation.) 
            ****************************************************************************************
            */
            CString CMD5Checksum::Final()
            {
            //Save number of bits
            BYTE Bits[8];
            DWordToByte( Bits, m_nCount, 
            8 );

            //Pad out to 56 mod 64.
            UINT nIndex = (UINT)((m_nCount[0>> 3& 0x3f);
            UINT nPadLen 
            = (nIndex < 56? (56 - nIndex) : (120 - nIndex);
            Update( PADDING, nPadLen );

            //Append length (before padding)
            Update( Bits, 8 );

            //Store final state in ''lpszMD5''
            const int nMD5Size = 16;
            unsigned 
            char lpszMD5[ nMD5Size ];
            DWordToByte( lpszMD5, m_lMD5, nMD5Size );

            //Convert the hexadecimal checksum to a CString
            CString strMD5;
            for ( int i=0; i < nMD5Size; i++
            {
              CString Str;
              
            if (lpszMD5[i] == 0) {
               Str 
            = CString("00");
              }
              
            else if (lpszMD5[i] <= 15)  {
               Str.Format(
            "0%x",lpszMD5[i]);
              }
              
            else {
               Str.Format(
            "%x",lpszMD5[i]);
              }

              ASSERT( Str.GetLength() 
            == 2 );
              strMD5 
            += Str;
            }
            ASSERT( strMD5.GetLength() 
            == 32 );
            return strMD5;
            }


            /*****************************************************************************************
            FUNCTION:  CMD5Checksum::Update
            DETAILS:  protected
            DESCRIPTION: Implementation of main MD5 checksum algorithm
            RETURNS:  void
            ARGUMENTS:  BYTE* Input    : input block
                UINT nInputLen : length of input block
            NOTES:   Computes the partial MD5 checksum for ''nInputLen'' bytes of data in ''Input''
            ****************************************************************************************
            */
            void CMD5Checksum::Update( BYTE* Input, ULONG nInputLen )
            {
            //Compute number of bytes mod 64
            UINT nIndex = (UINT)((m_nCount[0>> 3& 0x3F);

            //Update number of bits
            if ( ( m_nCount[0+= nInputLen << 3 )  <  ( nInputLen << 3) )
            {
              m_nCount[
            1]++;
            }
            m_nCount[
            1+= (nInputLen >> 29);

            //Transform as many times as possible.
            UINT i=0;  
            UINT nPartLen 
            = 64 - nIndex;
            if (nInputLen >= nPartLen)  
            {
              memcpy( 
            &m_lpszBuffer[nIndex], Input, nPartLen );
              Transform( m_lpszBuffer );
              
            for (i = nPartLen; i + 63 < nInputLen; i += 64
              {
               Transform( 
            &Input[i] );
              }
              nIndex 
            = 0;

            else 
            {
              i 
            = 0;
            }

            // Buffer remaining input
            memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i);
            }
            posted on 2007-10-08 03:13 七星重劍 閱讀(1839) 評論(0)  編輯 收藏 引用 所屬分類: Encrypt & Decrypt
            久久精品一区二区三区AV| 久久男人Av资源网站无码软件| 精品国产日韩久久亚洲| 国内精品久久久久久99| 久久亚洲欧洲国产综合| 久久国产热精品波多野结衣AV| 国产精品丝袜久久久久久不卡| 亚洲va久久久噜噜噜久久| 99久久精品免费| 69SEX久久精品国产麻豆| 区久久AAA片69亚洲 | 精品熟女少妇a∨免费久久| 久久婷婷色综合一区二区| 国产精品99久久久久久人| 久久精品国产亚洲av麻豆蜜芽| 伊人久久大香线蕉精品| 久久久噜噜噜www成人网| 99久久香蕉国产线看观香| 国产成人99久久亚洲综合精品| 国产人久久人人人人爽| 亚洲综合伊人久久大杳蕉| 亚洲精品97久久中文字幕无码| 国产精品日韩欧美久久综合| 久久国产精品久久精品国产| 久久久精品2019免费观看| A级毛片无码久久精品免费| 久久精品国产男包| 亚洲午夜久久久| 亚洲性久久久影院| 一级A毛片免费观看久久精品| 久久国产精品免费一区| 久久精品国产一区二区三区 | 久久精品国产2020| 深夜久久AAAAA级毛片免费看 | 乱亲女H秽乱长久久久| 久久AV高潮AV无码AV| 久久久久久久久久久| 久久久久亚洲av综合波多野结衣| 精品久久久久成人码免费动漫| 日韩精品久久久久久久电影| 综合久久一区二区三区 |