1. 程式人生 > >MD5演算法的C程式碼實現及測試

MD5演算法的C程式碼實現及測試

本程式主要是通過 rfc1321.txt 整理而來。這個檔案可以在下面的地址下載。

本程式在VC 2003 .NET 和 Dev C++ 4.9下編譯通過。

#include <stdio.h>

typedef struct {

unsigned int state[4];

unsigned int count[2];

unsigned char buffer[64];

} MD5Context;

void MD5_Init(MD5Context * context);

void MD5_Update(MD5Context * context, unsigned char * buf, int

len);

void MD5_Final(MD5Context * context, unsigned char digest[16]);

#define S11 7

#define S12 12

#define S13 17

#define S14 22

#define S21 5

#define S22 9

#define S23 14

#define S24 20

#define S31 4

#define S32 11

#define S33 16

#define S34 23

#define S41 6

#define S42 10

#define S43 15

#define S44 21

static unsigned char 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

};

#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) << (n)) | ((x) >> (32-(n))))

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

{/

(a) += F((b), (c), (d)) + (x) + (unsigned int)(ac);/

(a) = ROTATE_LEFT((a), (s));/

(a) += (b);/

}

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

{/

(a) += G((b), (c), (d)) + (x) + (unsigned int)(ac);/

(a) = ROTATE_LEFT((a), (s));/

(a) += (b);/

}

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

{/

(a) += H((b), (c), (d)) + (x) + (unsigned int)(ac);/

(a) = ROTATE_LEFT((a), (s));/

(a) += (b);/

}

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

{/

(a) += I((b), (c), (d)) + (x) + (unsigned int)(ac);/

(a) = ROTATE_LEFT((a), (s));/

(a) += (b);/

}

static void MD5_Encode(unsigned char * output, unsigned int * input, int len)

{

unsigned int i, j;

for (i = 0, j = 0; j < len; i++, j += 4)

{

output[j] = (unsigned char) (input[i] & 0xff);

output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);

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

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

}

}

static void MD5_Decode(unsigned int * output, unsigned char * input, int len)

{

unsigned int i, j;

for (i = 0, j = 0; j < len; i++, j += 4)

{

output[i] = ((unsigned int) input[j]) |

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

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

(((unsigned int) input[j + 3]) << 24);

}

}

static void MD5_Transform(unsigned int state[4], unsigned char block[64])

{

unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];

MD5_Decode(x, block, 64);

/* Round 1 */

FF(a, b, c, d, x[0], S11, 0xd76aa478);/* 1 */

FF(d, a, b, c, x[1], S12, 0xe8c7b756);/* 2 */

FF(c, d, a, b, x[2], S13, 0x242070db);/* 3 */

FF(b, c, d, a, x[3], S14, 0xc1bdceee);/* 4 */

FF(a, b, c, d, x[4], S11, 0xf57c0faf);/* 5 */

FF(d, a, b, c, x[5], S12, 0x4787c62a);/* 6 */

FF(c, d, a, b, x[6], S13, 0xa8304613);/* 7 */

FF(b, c, d, a, x[7], S14, 0xfd469501);/* 8 */

FF(a, b, c, d, x[8], S11, 0x698098d8);/* 9 */

FF(d, a, b, c, x[9], S12, 0x8b44f7af);/* 10 */

FF(c, d, a, b, x[10], S13, 0xffff5bb1);/* 11 */

FF(b, c, d, a, x[11], S14, 0x895cd7be);/* 12 */

FF(a, b, c, d, x[12], S11, 0x6b901122);/* 13 */

FF(d, a, b, c, x[13], S12, 0xfd987193);/* 14 */

FF(c, d, a, b, x[14], S13, 0xa679438e);/* 15 */

FF(b, c, d, a, x[15], S14, 0x49b40821);/* 16 */

/* Round 2 */

GG(a, b, c, d, x[1], S21, 0xf61e2562);/* 17 */

GG(d, a, b, c, x[6], S22, 0xc040b340);/* 18 */

GG(c, d, a, b, x[11], S23, 0x265e5a51);/* 19 */

GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);/* 20 */

GG(a, b, c, d, x[5], S21, 0xd62f105d);/* 21 */

GG(d, a, b, c, x[10], S22, 0x2441453);/* 22 */

GG(c, d, a, b, x[15], S23, 0xd8a1e681);/* 23 */

GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);/* 24 */

GG(a, b, c, d, x[9], S21, 0x21e1cde6);/* 25 */

GG(d, a, b, c, x[14], S22, 0xc33707d6);/* 26 */

GG(c, d, a, b, x[3], S23, 0xf4d50d87);/* 27 */

GG(b, c, d, a, x[8], S24, 0x455a14ed);/* 28 */

GG(a, b, c, d, x[13], S21, 0xa9e3e905);/* 29 */

GG(d, a, b, c, x[2], S22, 0xfcefa3f8);/* 30 */

GG(c, d, a, b, x[7], S23, 0x676f02d9);/* 31 */

GG(b, c, d, a, x[12], S24, 0x8d2a4c8a);/* 32 */

/* Round 3 */

HH(a, b, c, d, x[5], S31, 0xfffa3942);/* 33 */

HH(d, a, b, c, x[8], S32, 0x8771f681);/* 34 */

HH(c, d, a, b, x[11], S33, 0x6d9d6122);/* 35 */

HH(b, c, d, a, x[14], S34, 0xfde5380c);/* 36 */

HH(a, b, c, d, x[1], S31, 0xa4beea44);/* 37 */

HH(d, a, b, c, x[4], S32, 0x4bdecfa9);/* 38 */

HH(c, d, a, b, x[7], S33, 0xf6bb4b60);/* 39 */

HH(b, c, d, a, x[10], S34, 0xbebfbc70);/* 40 */

HH(a, b, c, d, x[13], S31, 0x289b7ec6);/* 41 */

HH(d, a, b, c, x[0], S32, 0xeaa127fa);/* 42 */

HH(c, d, a, b, x[3], S33, 0xd4ef3085);/* 43 */

HH(b, c, d, a, x[6], S34, 0x4881d05);/* 44 */

HH(a, b, c, d, x[9], S31, 0xd9d4d039);/* 45 */

HH(d, a, b, c, x[12], S32, 0xe6db99e5);/* 46 */

HH(c, d, a, b, x[15], S33, 0x1fa27cf8);/* 47 */

HH(b, c, d, a, x[2], S34, 0xc4ac5665);/* 48 */

/* Round 4 */

II(a, b, c, d, x[0], S41, 0xf4292244);/* 49 */

II(d, a, b, c, x[7], S42, 0x432aff97);/* 50 */

II(c, d, a, b, x[14], S43, 0xab9423a7);/* 51 */

II(b, c, d, a, x[5], S44, 0xfc93a039);/* 52 */

II(a, b, c, d, x[12], S41, 0x655b59c3);/* 53 */

II(d, a, b, c, x[3], S42, 0x8f0ccc92);/* 54 */

II(c, d, a, b, x[10], S43, 0xffeff47d);/* 55 */

II(b, c, d, a, x[1], S44, 0x85845dd1);/* 56 */

II(a, b, c, d, x[8], S41, 0x6fa87e4f);/* 57 */

II(d, a, b, c, x[15], S42, 0xfe2ce6e0);/* 58 */

II(c, d, a, b, x[6], S43, 0xa3014314);/* 59 */

II(b, c, d, a, x[13], S44, 0x4e0811a1);/* 60 */

II(a, b, c, d, x[4], S41, 0xf7537e82);/* 61 */

II(d, a, b, c, x[11], S42, 0xbd3af235);/* 62 */

II(c, d, a, b, x[2], S43, 0x2ad7d2bb);/* 63 */

II(b, c, d, a, x[9], S44, 0xeb86d391);/* 64 */

state[0] += a;

state[1] += b;

state[2] += c;

state[3] += d;

memset((char *) x, 0, sizeof(x));

}

void MD5_Init(MD5Context * context)

{

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

context->state[0] = 0x67452301;

context->state[1] = 0xefcdab89;

context->state[2] = 0x98badcfe;

context->state[3] = 0x10325476;

}

void MD5_Update(MD5Context * context, unsigned char * buf, int len)

{

unsigned int i, index, partLen;

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

if ((context->count[0] += ((unsigned int) len << 3)) < ((unsigned int) len << 3))

context->count[1]++;

context->count[1] += ((unsigned int) len >> 29);

partLen = 64 - index;

if (len >= partLen)

{

memcpy((char *) &context->buffer[index], (char *) buf, partLen);

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

for (i = partLen; i + 63 < len; i += 64)

MD5_Transform(context->state, &buf[i]);

index = 0;

}

else

{

i = 0;

}

memcpy((char *) &context->buffer[index], (char *) &buf[i], len - i);

}

void MD5_Final(MD5Context * context, unsigned char digest[16])

{

unsigned char bits[8];

unsigned int index, padLen;

MD5_Encode(bits, context->count, 8);

index = (unsigned int) ((context->count[0] >> 3) & 0x3f);

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

MD5_Update(context, PADDING, padLen);

MD5_Update(context, bits, 8);

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

memset((char *) context, 0, sizeof(*context));

}

void MD5_File (char * filename)

{

FILE *file;

MD5Context context;

unsigned char buff[16];

int i,len;

unsigned char buffer[0x0400];

if (!(file = fopen (filename, "rb")))

printf ("%s can't be opened/n", filename);

else

{

MD5_Init (&context);

while (len = fread (buffer, 1, 1024, file))

MD5_Update (&context, buffer, len);

MD5_Final(&context,buff);

fclose (file);

for(i=0;i<16;i++)

{

printf("%x",(buff[i] & 0xF0)>>4);

printf("%x",buff[i] & 0x0F);

}

printf("/n");

}

}

int main()

{

int i =0,j,len,startTime,endTime;

MD5Context context;

unsigned char buff[16];

char * str1 = "";

char * str2 = "abc";

char * str3 = "message digest";

char * str4 = "abcdefghijklmnopqrstuvwxyz";

char * str5 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

char * str6 = "12345678901234567890123456789012345678901234567890123456789012345678901234567890";

char str[7][100] =

{

"",

"a",

"abc",

"message digest",

"abcdefghijklmnopqrstuvwxyz",

"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",

"12345678901234567890123456789012345678901234567890123456789012345678901234567890"

};

for(i=0;i<6;i++)

{

len = strlen(str[i]);

MD5_Init(&context);

MD5_Update(&context,(unsigned char *)str[i], len);

MD5_Final(&context,buff);

printf("MD5(/"%s/") = /n",str[i]);

for(j=0;j<16;j++)

{

printf("%x",(buff[j] & 0xF0)>>4);

printf("%x",buff[j] & 0x0F);

}

printf("/n***********************************************************/n");

}

printf("Wating.../n");

MD5_File("00.dat");

system("pause");

return 0;

}

相關推薦

MD5演算法C程式碼實現測試

本程式主要是通過 rfc1321.txt 整理而來。這個檔案可以在下面的地址下載。 本程式在VC 2003 .NET 和 Dev C++ 4.9下編譯通過。 #include <stdio.h> typedef struct { unsigned int

WordCount程式碼實現測試

1.專案地址: 開發者:201631062515 201631062415 碼雲地址:https://gitee.com/heshuxiang/WordCount/tree/master 2.專案需求     對程式設計語言原始檔統計字元數、單詞數、行數,統計結果以指定格式輸出到預

Bellman-Ford演算法 C++/java實現 優化

Bellman-Ford演算法的核心就是對邊進行鬆弛操作 貼上c++原始碼 #include "stdafx.h" #pragma warning(disable:4996) #include <iostream> using namespace s

歸併排序演算法 C程式碼實現

合併排序(MERGE SORT)是又一類不同的排序方法,合併的含義就是將兩個或兩個以上的有序資料序列合併成一個新的有序資料序列,因此它又叫歸併演算法。它的基本思想就是假設陣列A有N個元素,那麼可以看成陣列A是又N個有序的子序列組成,每個子序列的長度為1,然後再兩兩合併,得到

九大排序演算法-C語言實現詳解

概述 排序有內部排序和外部排序,內部排序是資料記錄在記憶體中進行排序,而外部排序是因排序的資料很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。 我們這裡說說八大排序就是內部排序。     當n較大,則應採用時間複雜度為O(nlog2n)的排序方法:快

HASH演算法的簡單實現測試

一.hash_set之基石——雜湊表     hash_set的底層資料結構是雜湊表,因此要深入瞭解hash_set,必須先分析雜湊表。雜湊表是根據關鍵碼值(Key-Value)而直接進行訪問的資料結構,它用雜湊函式處理資料得到關鍵碼值,關鍵碼值對應表中一個特定

MD5演算法 —— C語言實現(字串的加密)

網上找到的實現md5函式程式碼,包括一個頭檔案md5.h和一個原始檔md5.c,用下面的測試程式碼test.c測試通過,各檔案依次如下: .h檔案——md5.h #ifndef MD5_H #define MD5_H typedef struct { unsi

KMP演算法C程式碼實現

一、初識KMP     理解KMP演算法需要關注2個問題:(請注意:字串下標從0開始。)     當i指標與j指標失配時:     1、當母串和模式串不匹配時,i指標為什麼不需要回溯?     2、當母串和模式串不匹配時,i指標不回溯,那麼j指標應該移動到哪?     通過

一致性hash演算法 java程式碼實現測試

轉載:http://blog.csdn.net/pcceo1/article/details/51493934 寫了一個一致性hash的Java實現程式碼,演算法是用別人的,據說很好,然後自己做了一個測試,用執行緒池起了1000個執行緒,每個執行緒hash10000次,模

各種排序演算法總結C#程式碼實現

 排序是計算機內經常進行的一種操作,其目的是將一組“無序”的記錄序列調整為“有序”的記錄序列。分內部排序和外部排序。若整個排序過程不需要訪問外存便能完成,則稱此類排序問題為內部排序。反之,若參加排序的記錄數量很大,整個序列的排序過程不可能在記憶體中完成,則稱此類排序問

影象去霧之何凱明暗通道先驗去霧演算法原理c++程式碼實現

http://blog.csdn.net/s12244315/article/details/50292049 何凱明博士,2007年清華大學畢業,2011年香港中文大學博士畢業,可謂是功力深厚,感嘆於國內一些所謂博士的水平,何這樣的博士才可以真正叫做

c#程式碼實現排序演算法之歸併排序

歸併排序的平均時間複雜度為O(nlogn),最好時間複雜度為O(nlogn),最壞時間複雜度為O(nlogn),空間複雜度為O(n),是一種穩定的演算法。 1.將待排序序列r(1),r(2),…,r(n)劃分為兩個長度相等的子序列r(1),…r(n/2)和r(n/2+1),…,r

c#程式碼實現排序演算法之快速排序

快速排序的平均時間複雜度為O(nlog2n),最好時間複雜度為O(nlog2n),最壞時間複雜度為O(n²),空間複雜度為O(log2n),是一種不穩定的演算法。 1.劃分:選定一個記錄作為軸值,以軸值為基準將整個序列劃分為兩個子序列r(1)…r(i-1)和r(i+1)…r(n)

c#程式碼實現排序演算法之氣泡排序

氣泡排序的平均時間複雜度為O(n²),最好時間複雜度為O(n),最壞時間複雜度為O(n²),空間複雜度為O(1),是一種穩定的演算法。 1.將整個待排序的記錄序列劃分成有序區和無序區,初始時有序區為空,無序區包括所有待排序的記錄。 2.對無序區從前向後依次比較相鄰記錄,若反序則交

c#程式碼實現排序演算法之選擇排序

選擇排序的平均時間複雜度為O(n²),最好時間複雜度為O(n²),最壞時間複雜度為O(n²),空間複雜度為O(1),是一種不穩定的演算法。 1.將整個記錄序列劃分為有序區和無序區,初始時有序區為空,無序區含有待排序的所有記錄。 2.在無序區查詢值最小的記錄,將它與無序區的第一個記

c#程式碼實現排序演算法之插入排序

插入排序的平均時間複雜度為O(n²),最好時間複雜度為O(n),最壞時間複雜度為O(n²),空間複雜度為O(1),是一種穩定的演算法。 1.將整個待排序的記錄序列劃分成有序區和無序區,初始時有序區為待排序記錄序列的第一個記錄,無序區包括所有剩餘待排序的記錄。 2.將無序區的第一個

單鏈表的C語言實現插入刪除演算法

什麼是單鏈表?   由於順序表在插入和刪除是需要做大量的元素移動工作,而且需要連續的物理空間,因此其缺點是十分明顯的,為了解決這一問題,不需要預先分配連續的記憶體地址空間、插入刪除元素不需要做大量移動工作的連結串列出現了。但解決問題的同時也擁有自己的缺點,即不能隨機存取。   在連結串列中,每個

特徵選擇mRMR演算法程式碼實現安裝下載

演算法程式碼實現連線可以直接下載解壓執行,在mac或者Linux系統下:https://github.com/csuldw/MachineLearning/tree/master/mRMR    要看懂result.out檔案結果中,有兩個關鍵字:*** MaxRel fea

MD5加密演算法C語言實現

md5.h #ifndef MD5_H #define MD5_H typedef struct { unsigned int count[2]; unsigned int state[4]; unsigned char buffe

PAT 1084外觀數列的程式碼實現錯誤分析(C語言)

題目 外觀數列是指具有以下特點的整數序列: d, d1, d111, d113, d11231, d112213111, ... 它從不等於 1 的數字 d 開始,序列的第 n+1 項是對第 n 項的描述。比如第 2 項表示第 1 項有 1 個 d,所以就是 d1;第