C++封装MD5加密方法,记录保存

md5_encode.h

/*
*******************************************************
* brief: md5 encryption
* author: Monkey.Knight
*******************************************************
*/

#ifndef __MD5_ENCODE_H__
#define __MD5_ENCODE_H__

// std
#include <string>

// define
#define UInt32 unsigned int
#define BIT_OF_BYTE  8
#define BIT_OF_GROUP 512
#define SRC_DATA_LEN 64

// 四个非线性函数宏定义
#define DEF_F(X, Y, Z ) ((( (X) & (Y) )|((~X)&(Z))))
#define DEF_G(X, Y, Z)  (((X)&(Z))|((Y)&(~Z)))
#define DEF_H(X, Y, Z)  ((X)^(Y)^(Z))
#define DEF_I(X, Y, Z)  ((Y)^((X)|(~Z)))

// 求链接数函数宏定义
#define FF(a, b, c, d, Mj, s, ti)  (a = b + CycleMoveLeft((a + DEF_F(b,c,d) + Mj + ti),s));
#define GG(a, b, c, d, Mj, s, ti)  (a = b + CycleMoveLeft((a + DEF_G(b,c,d) + Mj + ti),s));
#define HH(a, b, c, d, Mj, s, ti)  (a = b + CycleMoveLeft((a + DEF_H(b,c,d) + Mj + ti),s));
#define II(a, b, c, d, Mj, s, ti)  (a = b + CycleMoveLeft((a + DEF_I(b,c,d) + Mj + ti),s));


class Md5Encode {
public:
	// 4轮循环算法
	struct ParamDynamic {
		UInt32 ua_;
		UInt32 ub_;
		UInt32 uc_;
		UInt32 ud_;
		UInt32 va_last_;
		UInt32 vb_last_;
		UInt32 vc_last_;
		UInt32 vd_last_;
	};
public:
	Md5Encode() {
	}
	std::string Encode(std::string src_info);

protected:

	UInt32 CycleMoveLeft(UInt32 src_num, int bit_num_to_move);
	UInt32 FillData(const char* in_data_ptr, int data_byte_len, char** out_data_ptr);
	void RoundF(char* data_512_ptr, ParamDynamic& param);
	void RoundG(char* data_512_ptr, ParamDynamic& param);
	void RoundH(char* data_512_ptr, ParamDynamic& param);
	void RoundI(char* data_512_ptr, ParamDynamic& param);
	void RotationCalculate(char* data_512_ptr, ParamDynamic& param);
	std::string GetHexStr(unsigned int num_str);

private:
	// 幻数定义
	static const int kA;
	static const int kB;
	static const int kC;
	static const int kD;
	static const unsigned long long k_ti_num_integer;
};

#endif

md5_encode.cpp

#include "md5_encode.h"
#include <iostream>
// 幻数定义
const int Md5Encode::kA = 0x67452301;
const int Md5Encode::kB = 0xefcdab89;
const int Md5Encode::kC = 0x98badcfe;
const int Md5Encode::kD = 0x10325476;

const unsigned long long Md5Encode::k_ti_num_integer = 4294967296;

// function: CycleMoveLeft
// @param src_num:要左移的数
// @param bit_num_to_move:要移动的bit位数
// @return  循环左移后的结果数
UInt32 Md5Encode::CycleMoveLeft(UInt32 src_num, int bit_num_to_move) {
	UInt32 src_num1 = src_num;
	UInt32 src_num2 = src_num;
	if (0 >= bit_num_to_move) {
		return src_num;
	}
	UInt32 num1 = src_num1 << bit_num_to_move;
	UInt32 num2 = src_num2 >> (32 - bit_num_to_move);

	return ((src_num1 << bit_num_to_move) \
		| (src_num2 >> (32 - bit_num_to_move)));
}

// function: FillData
// @param in_data_ptr:    要加密的信息数据
// @param data_byte_len: 数据的字节数
// @param out_data_ptr:  填充必要信息后的数据
// return : 填充信息后的数据长度,以字节为单位
UInt32 Md5Encode::FillData(const char* in_data_ptr, int data_byte_len, char** out_data_ptr) {
	int bit_num = data_byte_len * BIT_OF_BYTE;
	int grop_num = bit_num / BIT_OF_GROUP;
	int mod_bit_num = bit_num % BIT_OF_GROUP;
	int bit_need_fill = 0;
	if (mod_bit_num > (BIT_OF_GROUP - SRC_DATA_LEN)) {
		bit_need_fill = (BIT_OF_GROUP - mod_bit_num);
		bit_need_fill += (BIT_OF_GROUP - SRC_DATA_LEN);
	}
	else {
		bit_need_fill = (BIT_OF_GROUP - SRC_DATA_LEN) - mod_bit_num; //  这里多加了一个BIT_OF_GROUP,避免bit_need_fill正好等于0,暂时不加
	}
	int all_bit = bit_num + bit_need_fill;
	if (0 < bit_need_fill) {
		*out_data_ptr = new char[all_bit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE];
		memset(*out_data_ptr, 0, all_bit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE);
		// copy data
		memcpy(*out_data_ptr, in_data_ptr, data_byte_len);
		// fill rest data
		unsigned char* tmp = reinterpret_cast<unsigned char*>(*out_data_ptr);
		tmp += data_byte_len;
		// fill 1 and 0
		*tmp = 0x80;
		// fill origin data len
		unsigned long long* origin_num = (unsigned long long*)((*out_data_ptr) + ((all_bit / BIT_OF_BYTE)));
		*origin_num = data_byte_len * BIT_OF_BYTE;
	}
	return (all_bit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE);
}

void Md5Encode::RoundF(char* data_BIT_OF_GROUP_ptr, ParamDynamic& param) {
	UInt32* M = reinterpret_cast<UInt32*>(data_BIT_OF_GROUP_ptr);
	int s[] = { 7, 12, 17, 22 };
	for (int i = 0; i < 16; ++i) {
		UInt32 ti = k_ti_num_integer * abs(sin(i + 1));
		if (i % 4 == 0) {
			FF(param.ua_, param.ub_, param.uc_, param.ud_, M[i], s[i % 4], ti);
		}
		else if (i % 4 == 1) {
			FF(param.ud_, param.ua_, param.ub_, param.uc_, M[i], s[i % 4], ti);
		}
		else if (i % 4 == 2) {
			FF(param.uc_, param.ud_, param.ua_, param.ub_, M[i], s[i % 4], ti);
		}
		else if (i % 4 == 3) {
			FF(param.ub_, param.uc_, param.ud_, param.ua_, M[i], s[i % 4], ti);
		}
	}
}

void Md5Encode::RoundG(char* data_BIT_OF_GROUP_ptr, ParamDynamic& param) {
	UInt32* M = reinterpret_cast<UInt32*>(data_BIT_OF_GROUP_ptr);
	int s[] = { 5, 9, 14, 20 };
	for (int i = 0; i < 16; ++i) {
		UInt32 ti = k_ti_num_integer * abs(sin(i + 1 + 16));
		int index = (i * 5 + 1) % 16;
		if (i % 4 == 0) {
			GG(param.ua_, param.ub_, param.uc_, param.ud_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 1) {
			GG(param.ud_, param.ua_, param.ub_, param.uc_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 2) {
			GG(param.uc_, param.ud_, param.ua_, param.ub_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 3) {
			GG(param.ub_, param.uc_, param.ud_, param.ua_, M[index], s[i % 4], ti);
		}
	}
}

void Md5Encode::RoundH(char* data_BIT_OF_GROUP_ptr, ParamDynamic& param) {
	UInt32* M = reinterpret_cast<UInt32*>(data_BIT_OF_GROUP_ptr);
	int s[] = { 4, 11, 16, 23 };
	for (int i = 0; i < 16; ++i) {
		UInt32 ti = k_ti_num_integer * abs(sin(i + 1 + 32));
		int index = (i * 3 + 5) % 16;
		if (i % 4 == 0) {
			HH(param.ua_, param.ub_, param.uc_, param.ud_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 1) {
			HH(param.ud_, param.ua_, param.ub_, param.uc_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 2) {
			HH(param.uc_, param.ud_, param.ua_, param.ub_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 3) {
			HH(param.ub_, param.uc_, param.ud_, param.ua_, M[index], s[i % 4], ti);
		}
	}
}

void Md5Encode::RoundI(char* data_BIT_OF_GROUP_ptr, ParamDynamic& param) {
	UInt32* M = reinterpret_cast<UInt32*>(data_BIT_OF_GROUP_ptr);
	int s[] = { 6, 10, 15, 21 };
	for (int i = 0; i < 16; ++i) {
		UInt32 ti = k_ti_num_integer * abs(sin(i + 1 + 48));
		int index = (i * 7 + 0) % 16;
		if (i % 4 == 0) {
			II(param.ua_, param.ub_, param.uc_, param.ud_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 1) {
			II(param.ud_, param.ua_, param.ub_, param.uc_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 2) {
			II(param.uc_, param.ud_, param.ua_, param.ub_, M[index], s[i % 4], ti);
		}
		else if (i % 4 == 3) {
			II(param.ub_, param.uc_, param.ud_, param.ua_, M[index], s[i % 4], ti);
		}
	}
}

void Md5Encode::RotationCalculate(char* data_512_ptr, ParamDynamic& param) {
	if (NULL == data_512_ptr) {
		return;
	}
	RoundF(data_512_ptr, param);
	RoundG(data_512_ptr, param);
	RoundH(data_512_ptr, param);
	RoundI(data_512_ptr, param);
	param.ua_ = param.va_last_ + param.ua_;
	param.ub_ = param.vb_last_ + param.ub_;
	param.uc_ = param.vc_last_ + param.uc_;
	param.ud_ = param.vd_last_ + param.ud_;

	param.va_last_ = param.ua_;
	param.vb_last_ = param.ub_;
	param.vc_last_ = param.uc_;
	param.vd_last_ = param.ud_;
}

// 转换成十六进制字符串输出
std::string Md5Encode::GetHexStr(unsigned int num_str) {
	std::string hexstr = "";
	char szch[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
	unsigned char* tmptr = (unsigned char*)&num_str;
	int len = sizeof(num_str);
	// 小端字节序,逆序打印
	for (int i = 0; i < len; i++) {
		unsigned char ch = tmptr[i] & 0xF0;
		ch = ch >> 4;
		hexstr.append(1, szch[ch]);
		ch = tmptr[i] & 0x0F;
		hexstr.append(1, szch[ch]);
	}
	return hexstr;
}

// function: Encode
// @param src_info:要加密的信息
// return :加密后的MD5值
std::string Md5Encode::Encode(std::string src_info) {
	ParamDynamic param;
	param.ua_ = kA;
	param.ub_ = kB;
	param.uc_ = kC;
	param.ud_ = kD;
	param.va_last_ = kA;
	param.vb_last_ = kB;
	param.vc_last_ = kC;
	param.vd_last_ = kD;

	std::string result;
	const char* src_data = src_info.c_str();
	char* out_data_ptr = NULL;
	int total_byte = FillData(src_data, strlen(src_data), &out_data_ptr);
	//char * data_BIT_OF_GROUP = out_data_ptr;
	for (int i = 0; i < total_byte / (BIT_OF_GROUP / BIT_OF_BYTE); ++i) {
		char* data_BIT_OF_GROUP = out_data_ptr;
		data_BIT_OF_GROUP += i * (BIT_OF_GROUP / BIT_OF_BYTE);
		RotationCalculate(data_BIT_OF_GROUP, param);
	}
	if (NULL != out_data_ptr) {
		delete[] out_data_ptr, out_data_ptr = NULL;
	}
	result.append(GetHexStr(param.ua_));
	result.append(GetHexStr(param.ub_));
	result.append(GetHexStr(param.uc_));
	result.append(GetHexStr(param.ud_));
	return result;
}

调用

string strText = "ceshiwenben";
Md5Encode encode_obj;
string retMd5 = encode_obj.Encode(strText);
cout<<"MD5:"<<retMd5.c_str()<<endl;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值