c++實現(xiàn)md5加密的代碼
更新時間:2022年06月18日 11:40:57 作者:Monkey.Knight
這篇文章主要介紹了c++實現(xiàn)md5加密的實例代碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
最近發(fā)現(xiàn)md5加密算法挺有趣,特點是單向加密不可逆,加密后的字符串長度相等,于是就用C++嘗試實現(xiàn)了一下
頭文件定義
/* ******************************************************* * 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 // 四個非線性函數(shù)宏定義 #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))) // 求鏈接數(shù)函數(shù)宏定義 #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輪循環(huán)算法 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: // 幻數(shù)定義 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
源文件:
#include "md5_encode.h" #include <iostream> // 幻數(shù)定義 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:要左移的數(shù) // @param bit_num_to_move:要移動的bit位數(shù) // @return 循環(huán)左移后的結果數(shù) 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: 要加密的信息數(shù)據(jù) // @param data_byte_len: 數(shù)據(jù)的字節(jié)數(shù) // @param out_data_ptr: 填充必要信息后的數(shù)據(jù) // return : 填充信息后的數(shù)據(jù)長度,以字節(jié)為單位 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); // 小端字節(jié)序,逆序打印 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; }
測試:
#include <iostream> #include <cmath> #include "md5_encode.h" int main(int argc, char* argv[]) { std::string src = "fasdfasdfasdfnmmw,enrsudfnsmndfejkjhuasdmnf"; Md5Encode encode_obj; std::string ret = encode_obj.Encode(src); std::cout << "info: " << src.c_str() << std::endl; std::cout << "md5: " << ret.c_str() << std::endl; return 0; }
結果:
info: fasdfasdfasdfnmmw,enrsudfnsmndfejkjhuasdmnf
md5: 01109ec97162a71ca5e67b5f059c3cac
到此這篇關于c++實現(xiàn)md5加密的文章就介紹到這了,更多相關c++ md5加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
數(shù)據(jù)結構課程設計-用棧實現(xiàn)表達式求值的方法詳解
本篇文章是對在c語言中用棧實現(xiàn)表達式求值的方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05