MD5 c++ 實現

MD5 c++ 實現

最近實現MD5算法,發現最頭疼的地方是對調試難以下手。衆所周知,MD5算法,只要輸入信息有一絲差別,結果就千差萬別,而且MD5算法原理並不難,實現的過程最頭疼的是細節,所以在此提供已實現完整功能的代碼及標註調試位置,方便大家調試

ps 本文不對MD5算法進行描述,因爲一般都要開發說明,或者可以搜索 “RFC 1321”,這個是MD5的標準說明,本文使用的檢驗例子也來源於此,不過其內容有點多且亂,可另尋他處。

結果運行

首先爲大家驗證結果,證明本程序的可靠性:
測試例子,來源:RFC 1321
在這裏插入圖片描述
運行結果:
在這裏插入圖片描述
讀者也可先獲取代碼,修改一下main函數,計算任意字符串的MD5,與網上的MD5加密工具結果進行對比
完整源碼:MD5 代碼(筆者GitHub)
以下爲兩個關鍵函數,思路和debug部分已註釋好,讀者可自行使用。算法涉及的小端模式,可參考大端模式和小端模式詳解

信息流讀取函數

/*
	此程序的信息讀取函數使用一種比較耗內存,但很容易寫的方法來實現:
	1)定義一個非常大的數組
	2)將所有元素按順序輸入數組
	3)讀取,填充和加入信息長度這些步驟全部完成後,將數組賦值給M[16],每16個就push到MessageFlow中(16*32 = 512)
	爲何要使用大數組?使用大數組,你就不需要考慮當前的信息是否要push,可以節省代碼,也可以減少if語句,降低程序的
	複雜性。
*/
void MD5::read(string str)
{
	unsigned int big_temp[1000] = {0};
	unsigned int sub_index = 0;
	unsigned int temp;
	big_temp[sub_index] = 0;
	int i;
	long long int   count = str.length() * 8;
	for (i = 0; i < str.length(); i++)//transfer message
	{
		temp = str[i];
		big_temp[sub_index] += temp << ((i % 4) * 8);
		if (i % 4 == 3)
			sub_index++;
	}

	temp = 0x80;//padding
	big_temp[sub_index] += temp << ((i % 4) * 8);
	if (i % 4 == 3)
		sub_index++;
	i++;
	temp = 0x00;
	while ((i * 8) % 512 != 448)
	{
		big_temp[sub_index] += temp << ((i % 4) * 8);
		if (i % 4 == 3)
			sub_index++;
		i++;
	}
	big_temp[sub_index++] = (count << 32) >> 32;
	big_temp[sub_index] = count >> 32;
	unsigned int * M;
	for (int i = 0; i <= sub_index; i++)//add message block to MessageFlow
	{
		if (i % 16 == 0)
		{
			M = new unsigned int[16];
		}
		else if (i % 16 == 15)
		{
			MessageFlow.push_back(M);
		}
		M[i % 16] = big_temp[i];
	}
	/*
	此處用於將輸入的信息print出來,主要驗證“小端存儲”操作是否出現錯誤。
	for (int i = 0; i < MessageFlow.size(); i++)
	{
		for (int j = 0; j < 16; j++)
		{
			printf("%x ", MessageFlow[i][j]);
		}
		cout << endl;
	}
	*/

}

循環壓縮函數:

void MD5::HMD5(int q)
{
	unsigned int a, b, c, d;
	a = A;
	b = B;
	c = C;
	d = D;
	unsigned int temp;
	unsigned int X, sub_index;
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 16; j++)
		{
			sub_index = i * 16 + j;
			X = MessageFlow[q][index[sub_index]];
			temp = a + g2(i, b, c, d) + X + T[sub_index];
			/*
				此處輸出的是官方給的數據的輸出,驗證數據是否出錯,注:T雖然可以臨時計算,但我看很多例子
				和官方代碼都是使用現成的T值,且我嘗試過直接算,一開始結果還是對的,到後面錯了很多,因此建議
				將T存入數組,直接使用就好。
				cout << index[sub_index] << " " << T[sub_index] << " " << s[sub_index] << endl;
			*/
			temp = (temp << s[sub_index]) | (temp >> (32 - s[sub_index]));
			a = b + temp;
			/*
				此處用於輸出a,若a輸出正確,說明以上步驟都是正確的。
				printf("%x\n",a);
			*/
			temp = d;
			d = c;
			c = b;
			b = a;
			a = temp;
		}
	}
	A = A + a;
	B = B + b;
	C = C + c;
	D = D + d;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章