Newer
Older
PhaseMeasure / common / utils / MD5.cpp
[wangxitong] on 22 Dec 2021 4 KB first commit
#include"MD5.h"

MD5::MD5()
{
	nullptr;
}

void MD5::MD5Encode
(
	_In_ const char* text,
	_In_ size_t len,
	_Inout_ char* dst
)
{
	//用于存放最终结果,以便转化为字符串
	short output[16];
	char dest[16];
	memset(dest, 0, SHORT_MD5_LEN);
	memset(dst, 0, CHAR_MD5_LEN);
	//四组幻数
	unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
	static const unsigned int k[64] =
	{
		0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
		0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
		0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
		0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
		0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
		0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
		0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
		0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
		0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
		0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
		0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
		0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
		0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
		0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
		0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
		0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
	};
	//四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数
	static const unsigned int qz[] =
	{
		7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
		5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
		4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
		6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
	};
	//每一轮所要读取的元素下表
	static const unsigned int s[] =
	{
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
		1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
		5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
		0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9
	};

	unsigned int i = 0, j = 0;
	//N*512+448
	//N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56
	//任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置
	size_t n_len = ((len + 8) / 64) * 64 + 56 + 8;
	unsigned char *n_text = (unsigned char *)malloc(n_len);
	memset(n_text, 0x00, n_len);
	memcpy(n_text, text, len);
	//末尾添加二进制1000 0000
	n_text[len] = 0x80;
	//追加长度
	//注意此处末尾添加的是一个64位的数据!!!
	unsigned char len_s[8];
	memset(len_s, 0x00, 8);
	unsigned long temp_len = 0x00000000;
	temp_len = (unsigned long)(len * 8);
	//此处注意,只拷贝4个字节数据,因为
	//unsigned long只有四个字节
	memcpy(len_s, &temp_len, 4);
	memcpy(n_text + (n_len-8), len_s, 8);

	//每64字节(512位)
	//处理一次,因为填充过后的数刚好是64的倍数
	for (j = 0; j < n_len; j += 64)
	{
		unsigned int H[4] = { 0,0,0,0 };
		memcpy(H, h, 4 * sizeof(unsigned int));
		//分段拷贝内容,以供处理多组数据
		unsigned char temp_text[64];
		memset(temp_text, 0x00, 64);
		memcpy(temp_text, n_text + j, 64);

		//一共循环64次,分为四组
		for (i = 0; i < 64; i++)
		{
			//四组非线性函数运算,用开关语句来判断是第几组
			// 0~16第一组,16~32第二组
			//32~48第三组,48~64第四组
			unsigned int R = 0, f = 0, tmp = 0;
			switch ((int)i / 16)
			{
			//H[1]=X,H[2]=Y,H[3]=Z
			//F(X,Y,Z)
			case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break;
			//G(X,Y,Z)
			case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break;
			//H(X,Y,Z)
			case 2: f = H[1] ^ H[2] ^ H[3]; break;
			//I
			case 3: f = H[2] ^ (H[1] | (~H[3]));  break;
			}
			//abcd分别交换位置
			tmp  = H[3];
			H[3] = H[2];
			H[2] = H[1];
			//R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节
			R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]);
			//b+((a+?(bcd)+M?+ti)<<s))
			H[1] = H[1] + ((R << qz[i]) | (R >> (32 - qz[i])));
			H[0] = tmp;
		}
		//每轮循环结束后,ABCD分别与abcd相加
		for (i = 0; i < 4; i++) h[i] += H[i];
	}

	free(n_text);
	memcpy(dest, h, 16);

	//与0xff位与将高位的ff变为00
	for (int i = 0; i < 16; i++)
		output[i] = dest[i] & 0xff;
	//将十六进制数据打印成字符串
	for (int i = 0; i < SHORT_MD5_LEN; i++)
		sprintf(dst + i * 2, "%02x", output[i]);
}


bool MD5::MD5StrValidate
(
	_In_ const char * input1,
	_In_ const char * input2
)
{
	if (strcmp(input1, input2) == 0)
		return true;
	return false;
}