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

猜你喜欢

转载自blog.csdn.net/qq_36303862/article/details/84889240