Principle and implementation of md5 algorithm

Message Digest Algorithm MD5 (Chinese name message digest algorithm fifth edition) is a hash function widely used in the field of computer security to provide message integrity protection. The file number of this algorithm is RFC 1321 (R. Rivest, MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992).

MD5 is Message-Digest Algorithm 5, which is used to ensure complete and consistent information transmission. It is one of the hash algorithms widely used by computers (also translated abstract algorithm, hash algorithm), and mainstream programming languages ​​have generally implemented MD5. Calculating data (such as Chinese characters) into another fixed-length value is the basic principle of the hash algorithm. The predecessors of MD5 are MD2, MD3, and MD4.

The MD5 algorithm has the following characteristics:

1. Compressibility: For any length of data, the calculated MD5 value length is fixed.

2, easy to calculate: Calculate the MD5 value from the original data is very easy.

3, anti-modification: any changes to the original data, even if only 1 byte is modified, the MD5 value obtained is very different.

4, strong anti-collision: Know the original data and its MD5 value, it is very difficult to find a data with the same MD5 value (ie forged data).

The role of MD5 is to allow large amounts of information to be "compressed" into a secure format (ie, a string of bytes of arbitrary length into a string of hexadecimal digits of a certain length) before the private key is signed by the digital signature software. In addition to MD5, the most famous ones are sha-1, RIPEMD and Haval.

Principle and implementation of md5 algorithm

Principle and Implementation of MD5 Algorithm I. MD5 Concept

MD5, the full name of Message Digest Algorithm 5, Chinese name is the fifth version of the message digest algorithm, a hash function widely used in the field of computer security to provide message integrity protection. The above paragraph is quoted from Baidu Encyclopedia. My understanding of MD5 is a message digest algorithm, which mainly converts text information into a short message digest, a combination of compression + encryption + hash algorithm through a specific hash hashing method. It is absolutely irreversible.

Second, MD5 calculation steps

MD5 processes the input information in 512-bit packets, and each packet is divided into 16 32-bit sub-packets. After a series of processing, the output of the algorithm consists of four 32-bit packets, and the four 32-bit packets are used. A 128-bit hash value is generated after the packet is cascaded.

First step, filling

If the length of the input information is not equal to 448 for the result of 512, the padding is required such that the result of the remainder of 512 is equal to 448. The method of padding is to fill a 1 and n 0s. After filling, the length of the message is N*512+448(bit);

The second step, record the length of the message

Use 64 bits to store the length of information before filling. These 64 bits are added after the first step result, so that the message length becomes N*512+448+64=(N+1)*512 bits.

The third step, loading the standard magic number (four integers)

The standard magic number (physical order) is (A = (01234567) 16, B = (89ABCDEF) 16, C = (FEDCBA98) 16, D = (76543210) 16). If it is defined in the program it should be (A=0X67452301L, B=0XEFCDAB89L, C=0X98BADCFEL, D=0X10325476L). A little dizzy, in fact, I will understand if I think about it.

The fourth step, four rounds of loop operations

The number of loops is the number of groups (N+1)

1) Subdivide each 512 bytes into 16 groups of 64 bits (8 bytes)

2) First recognize four linear functions (& is with, | is or, ~ is not, ^ is XOR)

[cpp] view plain copyF(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))

3) Let Mj denote the jth sub-packet of the message (from 0 to 15), "" s means that the left shift s bit, then the four operations are:

[cpp] view plain copyFF(a,b,c,d,Mj,s,TI) means a=b+((a+F(b,c,d)+Mj+TI)""s"

GG(a,b,c,d,Mj,s,TI) means a=b+((a+G(b,c,d)+Mj+TI)""s"

HH(a,b,c,d,Mj,s,ti) means a=b+((a+H(b,c,d)+Mj+ti)""s"

II (a, b, c, d, Mj, s, ti) means a = b + ((a + I (b, c, d) + Mj + ti) "" s)

4) Four-round operation

[cpp] view plain copy first round

a=FF(a,b,c,d,M0,7,0xd76aa478)

b=FF(d,a,b,c,M1,12,0xe8c7b756)

c=FF(c,d,a,b,M2,17,0x242070db)

d=FF(b,c,d,a,M3,22,0xc1bdceee)

a=FF(a,b,c,d,M4,7,0xf57c0faf)

b=FF(d,a,b,c,M5,12,0x4787c62a)

c=FF(c,d,a,b,M6,17,0xa8304613)

d=FF(b,c,d,a,M7,22,0xfd469501)

a=FF(a,b,c,d,M8,7,0x698098d8)

b=FF(d,a,b,c,M9,12,0x8b44f7af)

c=FF(c,d,a,b,M10,17,0xffff5bb1)

d=FF(b,c,d,a,M11,22,0x895cd7be)

a=FF(a,b,c,d,M12,7,0x6b901122)

b=FF(d,a,b,c,M13,12,0xfd987193)

c=FF(c,d,a,b,M14,17,0xa679438e)

d=FF(b,c,d,a,M15,22,0x49b40821)

second round

a=GG(a,b,c,d,M1,5,0xf61e2562)

b=GG(d,a,b,c,M6,9,0xc040b340)

c=GG(c,d,a,b,M11,14,0x265e5a51)

d=GG(b,c,d,a,M0,20,0xe9b6c7aa)

a=GG(a,b,c,d,M5,5,0xd62f105d)

b=GG(d,a,b,c,M10,9,0x02441453)

c=GG(c,d,a,b,M15,14,0xd8a1e681)

d=GG(b,c,d,a,M4,20,0xe7d3fbc8)

a=GG(a,b,c,d,M9,5,0x21e1cde6)

b=GG(d,a,b,c,M14,9,0xc33707d6)

c=GG(c,d,a,b,M3,14,0xf4d50d87)

d=GG(b,c,d,a,M8,20,0x455a14ed)

a=GG(a,b,c,d,M13,5,0xa9e3e905)

b=GG(d,a,b,c,M2,9,0xfcefa3f8)

c=GG(c,d,a,b,M7,14,0x676f02d9)

d=GG(b,c,d,a,M12,20,0x8d2a4c8a)

Third round

a=HH(a,b,c,d,M5,4,0xfffa3942)

b=HH(d,a,b,c,M8,11,0x8771f681)

c=HH(c,d,a,b,M11,16,0x6d9d6122)

d=HH(b,c,d,a,M14,23,0xfde5380c)

a=HH(a,b,c,d,M1,4,0xa4beea44)

b=HH(d,a,b,c,M4,11,0x4bdecfa9)

c=HH(c,d,a,b,M7,16,0xf6bb4b60)

d=HH(b,c,d,a,M10,23,0xbebfbc70)

a=HH(a,b,c,d,M13,4,0x289b7ec6)

b=HH(d,a,b,c,M0,11,0xeaa127fa)

c=HH(c,d,a,b,M3,16,0xd4ef3085)

d=HH(b,c,d,a,M6,23,0x04881d05)

a=HH(a,b,c,d,M9,4,0xd9d4d039)

b=HH(d,a,b,c,M12,11,0xe6db99e5)

c=HH(c,d,a,b,M15,16,0x1fa27cf8)

d=HH(b,c,d,a,M2,23,0xc4ac5665)

Fourth round

a=II(a,b,c,d,M0,6,0xf4292244)

b=II(d,a,b,c,M7,10,0x432aff97)

c=II(c,d,a,b,M14,15,0xab9423a7)

d=II(b,c,d,a,M5,21,0xfc93a039)

a=II(a,b,c,d,M12,6,0x655b59c3)

b=II(d,a,b,c,M3,10,0x8f0ccc92)

c=II(c,d,a,b,M10,15,0xffeff47d)

d=II(b,c,d,a,M1,21,0x85845dd1)

a=II(a,b,c,d,M8,6,0x6fa87e4f)

b=II(d,a,b,c,M15,10,0xfe2ce6e0)

c=II(c,d,a,b,M6,15,0xa3014314)

d=II(b,c,d,a,M13,21,0x4e0811a1)

a=II(a,b,c,d,M4,6,0xf7537e82)

b=II(d,a,b,c,M11,10,0xbd3af235)

c=II(c,d,a,b,M2,15,0x2ad7d2bb)

d=II(b,c,d,a,M9,21,0xeb86d391)

5) After each round of cycles, add A, B, C, and D to a, b, c, and d, respectively, and then proceed to the next cycle.

Third, MD5 application

1, consistency verification

A typical application of MD5 is to generate a summary of information for a piece of textual information to prevent tampering. It is often seen in some software information on some software download sites that its MD5 value, its role is that we can download the software, use a special software (such as Windows MD5 Check, etc.) to do a MD5 on the downloaded files. Check to make sure that the file we get is the same file as the one provided by the site.

2, digital certificate

If there is a third-party certification body, MD5 can also prevent the "rejection" of the author of the file. This is called the digital signature application.

3. Secure access authentication

In Unix systems, the user's password is stored in the file system via a hash operation using MD5 (or other similar algorithm). When the user logs in, the system performs the MD5 Hash operation on the password entered by the user, and then compares it with the MD5 value stored in the file system to determine whether the entered password is correct. Through such a procedure, the system can determine the legitimacy of the user's login system without knowing the plain code of the user's password.

Fourth, the source code

[cpp] view plain copy//MessageDigestAlgorithm5.h

#pragma once

#include"string"

#include"fstream"

#include《iostream》

Using namespace std;

Typedef unsigned char Byte;

Class CMessageDigestAlgorithm5

{

Public:

CMessageDigestAlgorithm5(void);

~CMessageDigestAlgorithm5(void);

/ / MD5 algorithm main function, encryption of str

String Encode(string &str);

String Encode(ifstream& infile);

Private:

Unsigned int F(unsigned int x, unsigned int y, unsigned int z);

Unsigned int G (unsigned int x, unsigned int y, unsigned int z);

Unsigned int H(unsigned int x, unsigned int y, unsigned int z);

Unsigned int I(unsigned int x, unsigned int y, unsigned int z);

Void Initialize();

Unsigned int LeftRotate(unsigned int opNumber,unsigned int opBit);

Void FF(unsigned int &a, unsigned int b, unsigned int c, unsigned int d, unsigned int Mj, unsigned int s, unsigned int Ti);

Void GG(unsigned int &a, unsigned int b, unsigned int c, unsigned int d, unsigned int Mj, unsigned int s, unsigned int Ti);

Void HH(unsigned int &a, unsigned int b, unsigned int c, unsigned int d, unsigned int Mj, unsigned int s, unsigned int Ti);

Void II (unsigned int &a, unsigned int b, unsigned int c, unsigned int d, unsigned int Mj, unsigned int s, unsigned int Ti);

Void ByteToUnsignedInt(const Byte* input, unsigned int* output, size_t length);

String ByteToHexString(const Byte* input, size_t length);

Void UnsignedIntToByte(const unsigned int * input, Byte* output, size_t length);

Void ProcessOfMDA5(const Byte block[64]);

Void EncodeByte(const Byte* input, size_t length);

Void Final();

Private:

Unsigned int m_ChainingVariable[4];

Unsigned int m_Count[2];

Byte m_Result[16];

Byte m_Buffer[64];

Enum

{

S11 = 7,

S12 = 12,

S13 = 17,

S14 = 22,

S21 = 5,

S22 = 9,

S23 = 14,

S24 = 20,

S31 = 4,

S32 = 11,

S33 = 16,

S34 = 23,

S41 = 6,

S42 = 10,

S43 = 15,

S44 = 21,

};

Static const Byte g_Padding[64];

};

[cpp] view plain copy//MessageDigestAlgorithm5.cpp

#include "stdafx.h"

#include "MessageDigestAlgorithm5.h"

Const Byte CMessageDigestAlgorithm5::g_Padding[64] = { 0x80 };//The first bit is 1 and the other is 0.

CMessageDigestAlgorithm5::CMessageDigestAlgorithm5(void)

{

}

CMessageDigestAlgorithm5::~CMessageDigestAlgorithm5(void)

{

}

Unsigned int CMessageDigestAlgorithm5::F(unsigned int x, unsigned int y,unsigned int z)

{

Return (x & y) | ((~ x) & z);

}

Unsigned int CMessageDigestAlgorithm5::G(unsigned int x, unsigned int y,unsigned int z)

{

Return (x & z) | (y & (~ z));

}

Unsigned int CMessageDigestAlgorithm5::H(unsigned int x, unsigned int y, unsigned int z)

{

Return x ^ y ^ z;

}

Unsigned int CMessageDigestAlgorithm5::I(unsigned int x, unsigned int y,unsigned int z)

{

Return y ^ (x | (~ z));

}

/************************************************* **

*Parameter: empty

* Function: Initialize link variables

* Return value: empty

************************************************** **/

Void CMessageDigestAlgorithm5::Initialize()

{

m_Count[0] = m_Count[1] = 0;

m_ChainingVariable[0] = 0x67452301;

m_ChainingVariable[1] = 0xefcdab89;

m_ChainingVariable[2] = 0x98badcfe;

m_ChainingVariable[3] = 0x10325476;

}

/************************************************* **

*Parameter: opNumber indicates the number to be shifted to the left

opBit indicates the number of digits shifted to the left

* Function: Complete the loop left shift operation

*Return value: the value after the left shift of the loop

************************************************** **/

Unsigned int CMessageDigestAlgorithm5::LeftRotate(unsigned int opNumber,unsigned int opBit)

{

Unsigned int left = opNumber;

Unsigned int right = opNumber;

Return (left " opBit) | (right " (32 - opBit));

}

Void CMessageDigestAlgorithm5::FF(unsigned int &a, unsigned int b,unsigned int c,unsigned int d, unsigned int Mj,unsigned int s,unsigned int Ti)

{

Unsigned int temp = a + F(b,c,d) + Mj + Ti;

a = b + LeftRotate(temp,s);

}

Void CMessageDigestAlgorithm5::GG(unsigned int &a, unsigned int b,unsigned int c,unsigned int d,unsigned int Mj,unsigned int s,unsigned int Ti)

{

Unsigned int temp = a + G(b,c,d) + Mj + Ti;

a = b + LeftRotate(temp,s);

}

Void CMessageDigestAlgorithm5::HH(unsigned int &a, unsigned int b,unsigned int c,unsigned int d, unsigned int Mj,unsigned int s,unsigned int Ti)

{

Unsigned int temp = a + H(b,c,d) + Mj + Ti;

a = b + LeftRotate(temp,s);

}

Void CMessageDigestAlgorithm5::II(unsigned int &a, unsigned int b,unsigned int c,unsigned int d, unsigned int Mj,unsigned int s,unsigned int Ti)

{

Unsigned int temp = a + I(b,c,d) + Mj + Ti;

a = b + LeftRotate(temp,s);

}

/************************************************* **

*Parameter: input represents the input byte array

Output means output unsigned int array

Length indicates the length of the input byte

* Function: byte to unsigned int (left low right high)

* Return value: empty

************************************************** **/

Void CMessageDigestAlgorithm5::ByteToUnsignedInt(const Byte* input, unsigned int* output, size_t length)

{

For(size_t i = 0,j = 0;j "length;++ i, j += 4)

{

Output[i] = ((static_cast"unsigned int"(input[j]))

|((static_cast"unsigned int"(input[j + 1])) "8)

|((static_cast"unsigned int"(input[j + 2])) "16)

|((static_cast"unsigned int"(input[j + 3])) "24));

}

}

/************************************************* **

*Parameter: input means input unsigned int array

Output represents the output byte array

Length indicates the length of the input byte

* Function: unsigned int to byte

* Return value: empty

************************************************** **/

Void CMessageDigestAlgorithm5::UnsignedIntToByte(const unsigned int * input, Byte* output, size_t length)

{

For (size_t i = 0, j = 0; j "length; ++i, j += 4)

{

Output[j] = static_cast "Byte" (input[i] & 0xff);

Output[j + 1] = static_cast "Byte" ((input[i]" 8) & 0xff);

Output[j + 2] = static_cast "Byte" ((input[i]" 16) & 0xff);

Output[j + 3] = static_cast "Byte" ((input[i]》》 24) & 0xff);

}

}

/************************************************* **

*Parameter: groups[] represents a 512-bit (64-byte) packet

*Function: Four-wheel main operation

* Return value: empty

************************************************** **/

Void CMessageDigestAlgorithm5::ProcessOfMDA5(const Byte groups[64])

{

Unsigned int a = m_ChainingVariable[0], b = m_ChainingVariable[1], c = m_ChainingVariable[2], d = m_ChainingVariable[3];

Unsigned int M[16];

ByteToUnsignedInt( groups, M, 64);

FF(a, b, c, d, M[ 0], S11, 0xd76aa478);

FF(d, a, b, c, M[ 1], S12, 0xe8c7b756);

FF(c, d, a, b, M[ 2], S13, 0x242070db);

FF(b, c, d, a, M[ 3], S14, 0xc1bdceee);

FF(a, b, c, d, M[ 4], S11, 0xf57c0faf);

FF(d, a, b, c, M[ 5], S12, 0x4787c62a);

FF(c, d, a, b, M[6], S13, 0xa8304613);

FF(b, c, d, a, M[7], S14, 0xfd469501);

FF(a, b, c, d, M[ 8], S11, 0x698098d8);

FF(d, a, b, c, M[9], S12, 0x8b44f7af);

FF(c, d, a, b, M[10], S13, 0xffff5bb1);

FF(b, c, d, a, M[11], S14, 0x895cd7be);

FF(a, b, c, d, M[12], S11, 0x6b901122);

FF(d, a, b, c, M[13], S12, 0xfd987193);

FF(c, d, a, b, M[14], S13, 0xa679438e);

FF(b, c, d, a, M[15], S14, 0x49b40821);

GG(a, b, c, d, M[ 1], S21, 0xf61e2562);

GG(d, a, b, c, M[6], S22, 0xc040b340);

GG(c, d, a, b, M[11], S23, 0x265e5a51);

GG(b, c, d, a, M[ 0], S24, 0xe9b6c7aa);

GG(a, b, c, d, M[ 5], S21, 0xd62f105d);

GG(d, a, b, c, M[10], S22, 0x2441453);

GG(c, d, a, b, M[15], S23, 0xd8a1e681);

GG(b, c, d, a, M[ 4], S24, 0xe7d3fbc8);

GG(a, b, c, d, M[9], S21, 0x21e1cde6);

GG(d, a, b, c, M[14], S22, 0xc33707d6);

GG(c, d, a, b, M[ 3], S23, 0xf4d50d87);

GG(b, c, d, a, M[ 8], S24, 0x455a14ed);

GG(a, b, c, d, M[13], S21, 0xa9e3e905);

GG(d, a, b, c, M[ 2], S22, 0xfcefa3f8);

GG(c, d, a, b, M[ 7], S23, 0x676f02d9);

GG(b, c, d, a, M[12], S24, 0x8d2a4c8a);

HH(a, b, c, d, M[ 5], S31, 0xfffa3942);

HH(d, a, b, c, M[ 8], S32, 0x8771f681);

HH(c, d, a, b, M[11], S33, 0x6d9d6122);

HH(b, c, d, a, M[14], S34, 0xfde5380c);

HH(a, b, c, d, M[ 1], S31, 0xa4beea44);

HH(d, a, b, c, M[ 4], S32, 0x4bdecfa9);

HH(c, d, a, b, M[7], S33, 0xf6bb4b60);

HH(b, c, d, a, M[10], S34, 0xbebfbc70);

HH(a, b, c, d, M[13], S31, 0x289b7ec6);

HH(d, a, b, c, M[ 0], S32, 0xeaa127fa);

HH(c, d, a, b, M[ 3], S33, 0xd4ef3085);

HH(b, c, d, a, M[6], S34, 0x4881d05);

HH(a, b, c, d, M[9], S31, 0xd9d4d039);

HH(d, a, b, c, M[12], S32, 0xe6db99e5);

HH(c, d, a, b, M[15], S33, 0x1fa27cf8);

HH(b, c, d, a, M[ 2], S34, 0xc4ac5665);

II(a, b, c, d, M[ 0], S41, 0xf4292244);

II(d, a, b, c, M[ 7], S42, 0x432aff97);

II(c, d, a, b, M[14], S43, 0xab9423a7);

II(b, c, d, a, M[ 5], S44, 0xfc93a039);

II(a, b, c, d, M[12], S41, 0x655b59c3);

II(d, a, b, c, M[ 3], S42, 0x8f0ccc92);

II(c, d, a, b, M[10], S43, 0xffeff47d);

II(b, c, d, a, M[ 1], S44, 0x85845dd1);

II(a, b, c, d, M[ 8], S41, 0x6fa87e4f);

II(d, a, b, c, M[15], S42, 0xfe2ce6e0);

II(c, d, a, b, M[6], S43, 0xa3014314);

II(b, c, d, a, M[13], S44, 0x4e0811a1);

II(a, b, c, d, M[ 4], S41, 0xf7537e82);

II(d, a, b, c, M[11], S42, 0xbd3af235);

II(c, d, a, b, M[ 2], S43, 0x2ad7d2bb);

II(b, c, d, a, M[9], S44, 0xeb86d391);

m_ChainingVariable[0] += a;

m_ChainingVariable[1] += b;

m_ChainingVariable[2] += c;

m_ChainingVariable[3] += d;

}

/************************************************* **

*Parameter: input represents the input byte array

Length indicates the input byte length = 16 (8 * 16 = 128 bit output)

* Function: byte to hexadecimal

*Return value: hexadecimal string

************************************************** **/

String CMessageDigestAlgorithm5::ByteToHexString(const Byte* input, size_t length)

{

Const char MapByteToHex[16] =

{

'0', '1', '2', '3',

'4', '5', '6', '7',

'8', '9', 'A', 'B',

'C', 'D', 'E', 'F'

};

String str;

For (size_t i = 0; i " length; ++ i)

{

Unsigned int temp = static_cast "unsigned int" (input[i]);

Unsigned int a = temp / 16;

Unsigned int b = temp % 16;

Str.append(1, MapByteToHex[a]);

Str.append(1, MapByteToHex[b]);

}

Return str;

}

/************************************************* **

*Parameter: str indicates the text to be encrypted

* Function: MD5 algorithm main function

*Return value: MD5 encrypted column value

************************************************** **/

String CMessageDigestAlgorithm5::Encode(string &str)

{

Initialize();

EncodeByte((const Byte * )(str.c_str()), str.length());

Final();

String strMD5 = ByteToHexString(m_Result,16);

Return strMD5;

}

/************************************************* **

*Parameter: infile indicates the file to be encrypted

* Function: MD5 algorithm main function

*Return value: MD5 encrypted column value

************************************************** **/

String CMessageDigestAlgorithm5::Encode(ifstream & infile)

{

If (!infile)

{

Return "";

}

Initialize();

Streamsize length;

String str;

Char buffer[1024];

While (! infile.eof())

{

Infile.read(buffer, 1024);

Length = infile.gcount();

If (length 》 0)

{

EncodeByte((const Byte* )buffer,length);

Final();

}

}

Infile.close();

String strMD5 = ByteToHexString(m_Result,16);

Return strMD5;

}

Void CMessageDigestAlgorithm5::EncodeByte(const Byte* input, size_t length)

{

Unsigned int index, partLen;

Size_t i;

Index = static_cast "unsigned int" ((m_Count[0]" 3) & 0x3f); / / converted to byte mod64

m_Count[0] += (static_cast "unsigned int" (length) "3"; / / bit number

If (m_Count[0] " (static_cast "unsigned int" (length) "3)

{

++m_Count[1];

}

m_Count[1] += (static_cast "unsigned int"(length)" 29);//

partLen = 64 - index;

If (length 》= partLen)

{

Memcpy(&m_Buffer[index], input, partLen);

ProcessOfMDA5(m_Buffer);

For (i = partLen; i + 63 " length; i += 64)

{

ProcessOfMDA5(&input[i]);

}

Index = 0;

}

Else

{

i = 0;

}

Memcpy(&m_Buffer[index], &input[i], length - i);

}

Void CMessageDigestAlgorithm5::Final()

{

Byte bits[8];

Unsigned int tempChainingVariable[4], tempCount[2];

Unsigned int index, padLen;

Memcpy(tempChainingVariable, m_ChainingVariable, 16);

Memcpy(tempCount, m_Count, 8);

UnsignedIntToByte(m_Count, bits, 8);

Index = static_cast "unsigned int" ((m_Count[0] 》) 3) & 0x3f);

padLen = (index " 56) ? (56 - index) : (120 - index);

EncodeByte(g_Padding, padLen);

EncodeByte(bits, 8);

UnsignedIntToByte(m_ChainingVariable,m_Result, 16);

Memcpy(m_ChainingVariable, tempChainingVariable, 16);

Memcpy(m_Count,tempCount, 8);

}

Principle and implementation of md5 algorithm

Five, instructions

For the MD5 algorithm, the byte stream generated by different read formats is different, and the calculation may require data format conversion. For example, converting bits into certain integer data is convenient for calculation. Therefore, different MD5 algorithm implementation versions are calculated. The results may vary greatly. Therefore, I think it is best to calculate the MD5 algorithm version multiple times. For the MD5 algorithm, there is a better online calculation tool, click on the MD5 online calculator. The MD5 algorithm is irreversible. However, based on the dictionary relationship principle of key-value pairs, there are some databases that collect massive MD5 information and abstracts. The enumeration method can find the original text information from the MD5 value, providing a similar tool, click MD5 online. Crack. In addition, here is the discussion community for MD5, click on MD5 to discuss the community.

Class 2 Power Adapter 9V

Class 2 Power Adapter 9V,Class 2 Power Adapter 120Vac 60Hz,Class 2 Power Ac Dc Adapter,Class 2 Power Adapter 9V 2A

ShenZhen Yinghuiyuan Electronics Co.,Ltd , https://www.yhypoweradapter.com