C + + implementation MD5 algorithm implementation code _c language

Source: Internet
Author: User
Tags md5

Test results and Baidu Encyclopedia test examples are consistent.

The implementation of the need to note: The last four variables a B C D link to the results, attention to the order of the variable high and low, specific reference to Linkresult () method.

Md5.h

Copy Code code as follows:



#ifndef _md5_h_


#define _md5_h_

#include <iostream>
#include <string>
using namespace Std;

Class MD5
{
Public
typedef unsigned char uchar8; Make sure it is 8bit
typedef char CHAR8; Make sure it is 8bit
MD5 ();

void Init ();

void UpdateMd5 (const UCHAR8 input[], const int length);


void UpdateMd5 (const CHAR8 input[], const int length);





void Finalize ();





void ComputMd5 (const UCHAR8 input[], const int length);


void ComputMd5 (const CHAR8 input[], const int length);





String GetMd5 ();





void PrintMd5 ();








Private


typedef unsigned int uint32; Make sure it is bit;


typedef unsigned long long UInt64; Make sure it is the bit;


UInt32 A, B, C, D;


const static int blocklen_ = 64; 512/8


The remain after last Updata (because MD5 May is computed segment by Segment)


Uchar8 Remain_[blocklen_];


int remainnum_; The number of Remain_ &lt; 64


UInt64 Totalinputbits_;


Uchar8 md5result_[16]; Bit style MD5 result,totally 128 bit


Char md5result_hex_[33]; hexadecimal style result; Md5result_hex_[32]= ' "


BOOL Isdone_; Indicate the Comput is finished;





Inline UInt32 rotateleft (const uint32 x, int n);


Inline UInt32 F (const uint32 x, const uint32 y, const uint32 z);


Inline UInt32 G (const uint32 x, const uint32 y, const uint32 z);


Inline UInt32 H (const uint32 x, const uint32 y, const uint32 z);


Inline UInt32 I (const uint32 x, const uint32 y, const uint32 z);


inline void FF (UInt32 &amp;a, const UInt32 B, const uint32 C, const UInt32 D,


Const UINT32 MJ, const int s, const uint32 TI);


inline void GG (UInt32 &amp;a, const UInt32 B, const uint32 C, const UInt32 D,


Const UINT32 MJ, const int s, const uint32 TI);


inline void HH (UInt32 &amp;a, const UInt32 B, const uint32 C, const UInt32 D,


Const UINT32 MJ, const int s, const uint32 TI);


inline void II (UInt32 &amp;a, const UInt32 B, const uint32 C, const UInt32 D,


Const UINT32 MJ, const int s, const uint32 TI);


void Uchartouint (UInt32 output[], const UCHAR8 input[], const unsigned int translength);

void Fourround (const UCHAR8 block[]);

void Linkresult ();

};

/* User Guide
   can comput the MD5 by using the funtion ComputMd5
   eg:
        MD5 m;
       md5::char8 str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
       m.computmd5 (str,sizeof (str)-1);  
        m.printmd5 ();

    If you are want to comput segment by Segment,you can does as follow, and Init () is suggested
 &nb sp;  the Begging,and Finalize () must call in "End:

        MD5 M;
        M.init ();
        md5::uchar8 str1[] = "ABCDEFGHIJKLMN";
        md5::uchar8 str2[] = "Opqrstuvwxyzabcdefghijk";
        md5::uchar8 str3[] = "LMNOPQRSTUVWXYZ";
        m.updatemd5 (str1,sizeof (STR1)-1);
        m.updatemd5 (str2,sizeof (STR2)-1);
        m.updatemd5 (str3,sizeof (STR3)-1);
        m.finalize ();
        m.printmd5 ();

If you are want to comput the MD5 of a file, you can use the interface of this program.
*/

#endif

Md5.cpp

Copy Code code as follows:



#include "md5.h"

#include <iostream>
using namespace Std;

const int S[4][4] = {7, 12, 17, 22,
5, 9, 14, 20,
4, 11, 16, 23,
6, 10, 15, 21};
void Md5::init ()
{
A = 0x67452301;
B = 0xefcdab89;
C = 0x98badcfe;
D = 0x10325476;
remainnum_ = 0;
Remain_[0] = ' the ';
Md5result_hex_[0] = ' the ';
Md5result_[0] = ' the ';
Totalinputbits_ = 0;
Isdone_ = false;
}

MD5::MD5 ()
{
Init ();
}

Inline Md5::uint32 md5::rotateleft (const uint32 x, int n)
{
return (x << N) | (x >> (32-n));
If X is signed, use: (x << N) | ((x & 0xFFFFFFFF) >> (32-n))
}
Inline Md5::uint32 md5::f (const uint32 x, const uint32 y, const UInt32 z)
{
Return (x & y) | ((~x) & Z);
}
Inline Md5::uint32 md5::g (const uint32 x, const uint32 y, const UInt32 z)
{
Return (X & Z) | (Y & (~z));
}
Inline Md5::uint32 md5::h (const uint32 x, const uint32 y, const UInt32 z)
{
return x ^ y ^ z;
}
Inline Md5::uint32 md5::i (const uint32 x, const uint32 y, const UInt32 z)
{
Return y ^ (x | (~z));
}

inline void Md5::ff (UInt32 &amp;a, const UInt32 B, const uint32 C, const UInt32 D,


Const UINT32 MJ, const int s, const uint32 TI)


{


A = B + rotateleft (A + F (b, C, D) + Mj + ti, s);


}


inline void Md5::gg (UInt32 &amp;a, const UInt32 B, const uint32 C, const UInt32 D,


Const UINT32 MJ, const int s, const uint32 TI)


{


A = B + rotateleft (A + G (b, C, D) + Mj + ti, s);


}


inline void Md5::hh (UInt32 &amp;a, const UInt32 B, const uint32 C, const UInt32 D,


Const UINT32 MJ, const int s, const uint32 TI)


{


A = B + rotateleft (A + H (b, C, D) + Mj + ti, s);


}


inline void Md5::ii (UInt32 &amp;a, const UInt32 B, const uint32 C, const UInt32 D,


Const UINT32 MJ, const int s, const uint32 TI)


{


A = B + rotateleft (A + I (b, C, D) + Mj + ti, s);


}

Link A B C D to result (bit style result and hexadecimal style result)


void Md5::linkresult ()


{


Bit style result


for (int i = 0; i &lt; 4; i++)//link A:low to High


{


Md5result_[i] = (A &gt;&gt; 8*i) &amp; 0xFF;


}


for (int i = 4; i&lt;8; i++)//link B:low to High


{


Md5result_[i] = (B &gt;&gt; 8* (i-4)) &amp; 0xFF;


}


for (int i = 8; i&lt;12; i++)//link C:low to High


{


Md5result_[i] = (C &gt;&gt; 8* (i-8)) &amp; 0xFF;


}


for (int i = i&lt;16; i++)//link D:low to High


{


Md5result_[i] = (D &gt;&gt; 8* (i-12)) &amp; 0xFF;


}

Change to hexadecimal style result
Note:it is not the same as simply link hex (A) Hex (B) Hex (C) Hex (D)
for (int i = 0; i < i++)
sprintf (& Md5result_hex_[i*2], "%02x", Md5result_[i]);
MD5RESULT_HEX_[32] = ' the ';

}

Print the MD5 by hex
void MD5::p rintMd5 ()
{
if (!isdone_)
{
cout<< "Error:computation is not finished" <<endl;

}
Else
cout<< "MD5 Value:" << md5result_hex_ <<endl;
}

Get the MD5 value of hex style
String Md5::getmd5 ()
{
if (!isdone_)
{
cout<< "Error:computation is not finished" <<endl;
Exit (0);
}
String A ((const char *) md5result_hex_);
return A;
}

void Md5::uchartouint (UInt32 output[], const UCHAR8 input[], const unsigned int translength)
{
for (int i = 0, j = 0; j < Translength; i++, j = 4)
{
Output[i] = ((UInt32) input[j]) | (((UInt32) input[j+1]) << 8) |
(((UInt32) input[j+2]) << 16) | (((UInt32) input[j+3]) << 24);
}
}

Four round on the A block of the bits;


void Md5::fourround (const UCHAR8 block[])


{


UInt32 A = a, B = b, c = c, d = D;


UInt32 m[16];


Uchartouint (M, block, Blocklen_); Blocklen_ is a const INT = 64;





Round 1


FF (A, B, C, D, m[0], s[0][0], 0xd76aa478);


FF (d, a, B, C, m[1], s[0][1], 0xe8c7b756);


FF (c, D, a, B, m[2], s[0][2], 0x242070db);


FF (b, C, D, A, m[3], s[0][3], 0xc1bdceee);


FF (A, B, C, D, m[4], s[0][0], 0XF57C0FAF);


FF (d, a, B, C, m[5], s[0][1], 0x4787c62a);


FF (c, D, a, B, m[6], s[0][2], 0xa8304613);


FF (b, C, D, A, m[7], s[0][3], 0xfd469501);


FF (A, B, C, D, m[8], s[0][0], 0X698098D8);


FF (d, a, B, C, m[9], s[0][1], 0X8B44F7AF);


FF (c, D, a, B, m[10], s[0][2], 0XFFFF5BB1);


FF (b, C, D, A, m[11], s[0][3], 0x895cd7be);


FF (A, B, C, D, m[12], s[0][0], 0x6b901122);


FF (d, a, B, C, m[13], s[0][1], 0xfd987193);


FF (c, D, a, B, m[14], s[0][2], 0xa679438e);


FF (b, C, D, A, m[15], s[0][3], 0x49b40821);

Round 2


GG (A, B, C, D, m[1], s[1][0], 0xf61e2562);


GG (d, a, B, C, m[6], s[1][1], 0xc040b340);


GG (c, D, a, B, m[11], s[1][2], 0x265e5a51);


GG (b, C, D, A, m[0], s[1][3], 0XE9B6C7AA);


GG (A, B, C, D, m[5], s[1][0], 0xd62f105d);


GG (d, a, B, C, m[10], s[1][1], 0x2441453);


GG (c, D, a, B, m[15], s[1][2], 0xd8a1e681);


GG (b, C, D, A, m[4], s[1][3], 0XE7D3FBC8);


GG (A, B, C, D, m[9], s[1][0], 0x21e1cde6);


GG (d, a, B, C, m[14], s[1][1], 0xc33707d6);


GG (c, D, a, B, m[3], s[1][2], 0xf4d50d87);


GG (b, C, D, A, m[8], s[1][3], 0x455a14ed);


GG (A, B, C, D, m[13], s[1][0], 0xa9e3e905);


GG (d, a, B, C, m[2], s[1][1], 0xfcefa3f8);


GG (c, D, a, B, m[7], s[1][2], 0x676f02d9);


GG (b, C, D, A, m[12], s[1][3], 0x8d2a4c8a);

Round 3


HH (A, B, C, D, m[5], s[2][0], 0xfffa3942);


HH (d, a, B, C, m[8], s[2][1], 0x8771f681);


HH (c, D, a, B, m[11], s[2][2], 0x6d9d6122);


HH (b, C, D, A, m[14], s[2][3], 0xfde5380c);


HH (A, B, C, D, m[1], s[2][0], 0xa4beea44);


HH (d, a, B, C, m[4], s[2][1], 0x4bdecfa9);


HH (c, D, a, B, m[7], s[2][2], 0xf6bb4b60);


HH (b, C, D, A, m[10], s[2][3], 0XBEBFBC70);


HH (A, B, C, D, m[13], s[2][0], 0x289b7ec6);


HH (d, a, B, C, m[0], s[2][1], 0XEAA127FA);


HH (c, D, a, B, m[3], s[2][2], 0xd4ef3085);


HH (b, C, D, A, m[6], s[2][3], 0x4881d05);


HH (A, B, C, D, m[9], s[2][0], 0xd9d4d039);


HH (d, a, B, C, m[12], s[2][1], 0xe6db99e5);


HH (c, D, a, B, m[15], s[2][2], 0x1fa27cf8);


HH (b, C, D, A, m[2], s[2][3], 0xc4ac5665);





Round 4


II (A, B, C, D, m[0], s[3][0], 0xf4292244);


II (d, a, B, C, m[7], s[3][1], 0x432aff97);


II (c, D, a, B, m[14], s[3][2], 0xab9423a7);


II (b, C, D, A, m[5], s[3][3], 0xfc93a039);


II (A, B, C, D, m[12], s[3][0], 0x655b59c3);


II (d, a, B, C, m[3], s[3][1], 0x8f0ccc92);


II (c, D, a, B, m[10], s[3][2], 0xffeff47d);


II (b, C, D, A, m[1], s[3][3], 0X85845DD1);


II (A, B, C, D, m[8], s[3][0], 0x6fa87e4f);


II (d, a, B, C, m[15], s[3][1], 0xfe2ce6e0);


II (c, D, a, B, m[6], s[3][2], 0xa3014314);


II (b, C, D, A, m[13], s[3][3], 0X4E0811A1);


II (A, B, C, D, m[4], s[3][0], 0xf7537e82);


II (d, a, B, C, m[11], s[3][1], 0xbd3af235);


II (c, D, a, B, m[2], s[3][2], 0X2AD7D2BB);


II (b, C, D, A, m[9], s[3][3], 0xeb86d391);





A + A;


B + B;


C + + C;


D + + D;


}

Update Md5,must consider the Remain_.
void Md5::updatemd5 (const UCHAR8 input[], const int length)
{
Isdone_ = false;
Totalinputbits_ + = (length << 3);

int start = Blocklen_-remainnum_; Blocklen_ = 64
Copy a part of input to remain_ so it can form a block (size=64)

if (start <= length)
{
Can form a block,then do fourround to this block
memcpy (&remain_[remainnum_], input, start);
Fourround (Remain_);

int i;


for (i = start; I &lt;= length-blocklen_ i + = Blocklen_)


{


Fourround (&amp;input[i]);


}


Remainnum_ = Length-i;


memcpy (Remain_, &amp;input[i], remainnum_);


}


Else


{


Can not form a blocks, function return;


memcpy (&amp;remain_[remainnum_], input, length);


remainnum_ = length;


}





}

void Md5::updatemd5 (const CHAR8 input[], const int length)
{
UPDATEMD5 ((const UCHAR8 *) input, length);
}

Padding with 100000 ... To Remain_ and add the 64bit original size of input


void Md5::finalize ()


{


if (Isdone_ = = True)


Return





Uchar8 padding[64] = {


0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,


0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,


0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0


};





int temp = 56-REMAINNUM_; 56 = 448/8


if (Temp &gt; 0)


{


UPDATEMD5 (padding, temp);


Totalinputbits_-= (temp &lt;&lt; 3);


}


else if (Temp &lt; 0)


{


UpdateMd5 (padding, + temp);


Totalinputbits_-= ((+ temp) &lt;&lt; 3);


}





Trans Totalinputbits_ to Uchar8 (64bits)


Uchar8 Bits[8];


for (int i = 0; i &lt; 8; i++)


{


Bits[i] = (totalinputbits_ &gt;&gt; 8*i) &amp; 0xFF;


}





UPDATEMD5 (Bits, 8); Add the number of original input (the last 64bits)





Linkresult ();


Isdone_ = true;


}

Comput the MD5 based on input, (just this one input)
void Md5::computmd5 (const UCHAR8 input[], const int length)
{
Init ();
UPDATEMD5 (input, length);
Finalize ();
}

void Md5::computmd5 (const CHAR8 input[], const int length)
{
COMPUTMD5 ((const UCHAR8 *) input, length);
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.