C/C++編程學習:MD5算法代碼實現

 

 

 

 

咱們在計算算法的時候,一般都會使用MD5加密算法,而通常實現這些操做都以來函數,下面是C/C++MD5算法的實現代碼,但願能爲你帶來幫助。算法

md5簡介編程

消息摘要算法第五版(英語:Message-Digest Algorithm 5,縮寫爲MD5),是當前計算機領域用於確保信息傳輸完整一致而普遍使用的散列算法之一(又譯哈希算法、摘要算法等),主流編程語言廣泛已有MD5的實現。緩存

將數據 (如一段文字)運算變爲另外一固定長度值,是散列算法的基礎原理,MD5的前身有MD二、MD3和MD4。MD5由MD四、MD三、MD2改進而來,主要加強算法複雜度和不可逆性。服務器

目前,MD5算法因其廣泛、穩定、快速的特色,仍普遍應用於普通 數據的錯誤檢查領域。例如在一些BitTorrent下載中,軟件將經過計算MD5檢驗下載到的文件片斷的完整性。編程語言

MD5已經普遍使用在爲文件傳輸提供必定的可靠性方面。例如,服務器預先提供一個MD5校驗和,用戶下載完文件之後, 用MD5算法計算下載文件的MD5校驗和,而後經過檢查這兩個校驗和是否一致,就能判斷下載的文件是否出錯。函數

MD5是輸入不定長度信息,輸出固定長度128-bits的算法。通過程序流程,生成四個32位數據,最後聯合起來成爲一個 128-bits散列。基本方式爲,求餘、取餘、調整長度、與連接變量進行循環運算。得出結果。學習

md5算法描述測試

假設輸入信息(input message)的長度爲b(bit),咱們想要產生它的報文摘要,在此處b爲任意的非負整數:b也可能爲0,也不必定爲8的整數倍,且多是任意大的長度。設該信息的比特流表示以下: M[0] M[1] M[2] ... M[b-1] 計算此信息的報文摘要須要以下5步:加密

1.補位spa

信息計算前先要進行位補位,設補位後信息的長度爲LEN(bit),則LEN%512 = 448(bit),即數據擴展至 K * 512 + 448(bit)。即K * 64+56(byte),K爲整數。補位操做始終要執行,即便補位前信息的長度對512求餘的結果是448。具體補位操做:補一個1,而後補0至知足上述要求。總共最少要補1bit,最多補512bit。

2.尾部加上信息長度

將輸入信息的原始長度b(bit)表示成一個64-bit的數字,把它添加到上一步的結果後面(在32位的機器上,這64位將用2個字來表示而且低位在前)。當遇到b大於2^64這種極少的狀況時,b的高位被截去,僅使用b的低64位。

通過上面兩步,數據就被填補成長度爲512(bit)的倍數。也就是說,此時的數據長度是16個字(32byte)的整數倍。此時的數據表示爲: M[0 ... N-1] 其中的N是16的倍數。

3.初始化緩存區

用一個四個字的緩衝器(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

4.轉換

首先定義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))

FF(a,b,c,d,Mj,s,ti)表示 a = b + ((a + F(b,c,d) + Mj + ti)

下面是MD5算法的具體的實現

MD5算法的頭文件Md5.h:

#ifndef MD5_H

#define MD5_H

typedef struct

{

unsigned int count[2];

unsigned int state[4];

unsigned char buffer[64];

}MD5_CTX;

#define F(x,y,z) ((x & y) | (~x & z))

#define G(x,y,z) ((x & z) | (y & ~z))

#define H(x,y,z) (x^y^z)

#define I(x,y,z) (y ^ (x | ~z))

#define ROTATE_LEFT(x,n) ((x > (32-n)))

#define FF(a,b,c,d,x,s,ac) { \

a += F(b, c, d) + x + ac; \

a = ROTATE_LEFT(a, s); \

a += b; \

}

#define GG(a,b,c,d,x,s,ac) { \

a += G(b, c, d) + x + ac; \

a = ROTATE_LEFT(a, s); \

a += b; \

}

#define HH(a,b,c,d,x,s,ac) { \

a += H(b, c, d) + x + ac; \

a = ROTATE_LEFT(a, s); \

a += b; \

}

#define II(a,b,c,d,x,s,ac) { \

a += I(b, c, d) + x + ac; \

a = ROTATE_LEFT(a, s); \

a += b; \

}

void MD5Init(MD5_CTX *context);

void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);

void MD5Final(MD5_CTX *context, unsigned char digest[16]);

void MD5Transform(unsigned int state[4], unsigned char block[64]);

void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);

void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);

#endif

MD5算法的實現文件Md5.cpp:

unsigned char PADDING[] = {

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 };

//在逆向代碼的時候,須要關注下面的特徵值

void MD5Init(MD5_CTX *context)

{

context->count[0] = 0;

context->count[1] = 0;

context->state[0] = 0x67452301;

context->state[1] = 0xEFCDAB89;

context->state[2] = 0x98BADCFE;

context->state[3] = 0x10325476;

}

void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen)

{

unsigned int i = 0, index = 0, partlen = 0;

index = (context->count[0] >> 3) & 0x3F;

partlen = 64 - index;

context->count[0] += inputlen count[0] count[1]++;

context->count[1] += inputlen >> 29;

if (inputlen >= partlen)

{

memcpy(&context->buffer[index], input, partlen);

MD5Transform(context->state, context->buffer);

for (i = partlen; i + 64 state, &input[i]);

index = 0;

}

else

{

i = 0;

}

memcpy(&context->buffer[index], &input[i], inputlen - i);

}

void MD5Final(MD5_CTX *context, unsigned char digest[16])

{

unsigned int index = 0, padlen = 0;

unsigned char bits[8];

index = (context->count[0] >> 3) & 0x3F;

padlen = (index count, 8);

MD5Update(context, PADDING, padlen);

MD5Update(context, bits, 8);

MD5Encode(digest, context->state, 16);

}

void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len)

{

unsigned int i = 0, j = 0;

while (j > 8) & 0xFF;

output[j + 2] = (input[i] >> 16) & 0xFF;

output[j + 3] = (input[i] >> 24) & 0xFF;

i++;

j += 4;

}

}

void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len)

{

unsigned int i = 0, j = 0;

while (j

MD5算法的調用測試:

int _tmain(int argc, _TCHAR* argv[])

{

int i;

unsigned char encrypt[] = "admin";//21232f297a57a5a743894a0e4a801fc3

unsigned char decrypt[16];

MD5_CTX md5;

MD5Init(&md5);

MD5Update(&md5, encrypt, strlen((char *)encrypt));

MD5Final(&md5, decrypt);

//Md5加密後的32位結果

printf("加密前:%s\n加密後16位:", encrypt);

分享(源碼、項目實戰視頻、項目筆記,基礎入門教程)

歡迎轉行和學習編程的夥伴,利用更多的資料學習成長比本身琢磨更快哦!

免費學習書籍:


 

免費學習資料:

相關文章
相關標籤/搜索