#include #include #include #include #include #include class SimpleMD5 { private: // 基础函数定义 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) // 循环左移 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) // 转换函数 #define FF(a, b, c, d, x, s, ac) { \ (a) += F((b), (c), (d)) + (x) + (ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G((b), (c), (d)) + (x) + (ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H((b), (c), (d)) + (x) + (ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I((b), (c), (d)) + (x) + (ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } uint32_t state[4]; // 状态变量 (A, B, C, D) // 填充数据 void pad(std::vector& data) { uint64_t original_bit_length = data.size() * 8; // 添加 1 bit (0x80 字节) data.push_back(0x80); // 填充 0 直到长度对 64 取模等于 56 while ((data.size() % 64) != 56) { data.push_back(0x00); } // 添加原始消息长度 (小端序) for (int i = 0; i < 8; i++) { data.push_back(static_cast(original_bit_length >> (i * 8))); } } // 转换 4 字节为 32 位整数 (小端序) uint32_t to_int32(const uint8_t* bytes) { return (static_cast(bytes[0])) | (static_cast(bytes[1]) << 8) | (static_cast(bytes[2]) << 16) | (static_cast(bytes[3]) << 24); } // 主转换函数 void transform(const uint8_t block[64]) { uint32_t a = state[0]; uint32_t b = state[1]; uint32_t c = state[2]; uint32_t d = state[3]; uint32_t x[16]; // 将 64 字节块解码为 16 个 32 位整数 for (int i = 0, j = 0; i < 16; i++, j += 4) { x[i] = to_int32(&block[j]); } /* 第 1 轮 */ FF(a, b, c, d, x[0], 7, 0xd76aa478); FF(d, a, b, c, x[1], 12, 0xe8c7b756); FF(c, d, a, b, x[2], 17, 0x242070db); FF(b, c, d, a, x[3], 22, 0xc1bdceee); FF(a, b, c, d, x[4], 7, 0xf57c0faf); FF(d, a, b, c, x[5], 12, 0x4787c62a); FF(c, d, a, b, x[6], 17, 0xa8304613); FF(b, c, d, a, x[7], 22, 0xfd469501); FF(a, b, c, d, x[8], 7, 0x698098d8); FF(d, a, b, c, x[9], 12, 0x8b44f7af); FF(c, d, a, b, x[10], 17, 0xffff5bb1); FF(b, c, d, a, x[11], 22, 0x895cd7be); FF(a, b, c, d, x[12], 7, 0x6b901122); FF(d, a, b, c, x[13], 12, 0xfd987193); FF(c, d, a, b, x[14], 17, 0xa679438e); FF(b, c, d, a, x[15], 22, 0x49b40821); /* 第 2 轮 */ GG(a, b, c, d, x[1], 5, 0xf61e2562); GG(d, a, b, c, x[6], 9, 0xc040b340); GG(c, d, a, b, x[11], 14, 0x265e5a51); GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); GG(a, b, c, d, x[5], 5, 0xd62f105d); GG(d, a, b, c, x[10], 9, 0x02441453); GG(c, d, a, b, x[15], 14, 0xd8a1e681); GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); GG(a, b, c, d, x[9], 5, 0x21e1cde6); GG(d, a, b, c, x[14], 9, 0xc33707d6); GG(c, d, a, b, x[3], 14, 0xf4d50d87); GG(b, c, d, a, x[8], 20, 0x455a14ed); GG(a, b, c, d, x[13], 5, 0xa9e3e905); GG(d, a, b, c, x[2], 9, 0xfcefa3f8); GG(c, d, a, b, x[7], 14, 0x676f02d9); GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 第 3 轮 */ HH(a, b, c, d, x[5], 4, 0xfffa3942); HH(d, a, b, c, x[8], 11, 0x8771f681); HH(c, d, a, b, x[11], 16, 0x6d9d6122); HH(b, c, d, a, x[14], 23, 0xfde5380c); HH(a, b, c, d, x[1], 4, 0xa4beea44); HH(d, a, b, c, x[4], 11, 0x4bdecfa9); HH(c, d, a, b, x[7], 16, 0xf6bb4b60); HH(b, c, d, a, x[10], 23, 0xbebfbc70); HH(a, b, c, d, x[13], 4, 0x289b7ec6); HH(d, a, b, c, x[0], 11, 0xeaa127fa); HH(c, d, a, b, x[3], 16, 0xd4ef3085); HH(b, c, d, a, x[6], 23, 0x04881d05); HH(a, b, c, d, x[9], 4, 0xd9d4d039); HH(d, a, b, c, x[12], 11, 0xe6db99e5); HH(c, d, a, b, x[15], 16, 0x1fa27cf8); HH(b, c, d, a, x[2], 23, 0xc4ac5665); /* 第 4 轮 */ II(a, b, c, d, x[0], 6, 0xf4292244); II(d, a, b, c, x[7], 10, 0x432aff97); II(c, d, a, b, x[14], 15, 0xab9423a7); II(b, c, d, a, x[5], 21, 0xfc93a039); II(a, b, c, d, x[12], 6, 0x655b59c3); II(d, a, b, c, x[3], 10, 0x8f0ccc92); II(c, d, a, b, x[10], 15, 0xffeff47d); II(b, c, d, a, x[1], 21, 0x85845dd1); II(a, b, c, d, x[8], 6, 0x6fa87e4f); II(d, a, b, c, x[15], 10, 0xfe2ce6e0); II(c, d, a, b, x[6], 15, 0xa3014314); II(b, c, d, a, x[13], 21, 0x4e0811a1); II(a, b, c, d, x[4], 6, 0xf7537e82); II(d, a, b, c, x[11], 10, 0xbd3af235); II(c, d, a, b, x[2], 15, 0x2ad7d2bb); II(b, c, d, a, x[9], 21, 0xeb86d391); state[0] += a; state[1] += b; state[2] += c; state[3] += d; } public: SimpleMD5() { reset(); } // 重置状态 void reset() { state[0] = 0x67452301; state[1] = 0xefcdab89; state[2] = 0x98badcfe; state[3] = 0x10325476; } // 计算字符串的 MD5 std::string hash(const std::string& input) { return hash(reinterpret_cast(input.c_str()), input.length()); } // 计算字节数组的 MD5 std::string hash(const uint8_t* data, size_t length) { reset(); // 将数据复制到 vector 以便填充 std::vector buffer(data, data + length); // 填充数据 pad(buffer); // 处理每个 64 字节块 for (size_t i = 0; i < buffer.size(); i += 64) { transform(&buffer[i]); } // 将结果转换为十六进制字符串 return to_hex_string(); } // 计算文件的 MD5 std::string hash_file(const std::string& filename) { reset(); FILE* file = fopen(filename.c_str(), "rb"); if (!file) { return ""; } std::vector buffer; uint8_t chunk[1024]; size_t bytes_read; while ((bytes_read = fread(chunk, 1, sizeof(chunk), file)) > 0) { buffer.insert(buffer.end(), chunk, chunk + bytes_read); } fclose(file); return hash(buffer.data(), buffer.size()); } private: // 将结果转换为十六进制字符串 std::string to_hex_string() { std::stringstream ss; ss << std::hex << std::setfill('0'); // 以小端序输出每个状态变量 for (int i = 0; i < 4; i++) { // 将 32 位整数按字节输出 for (int j = 0; j < 4; j++) { uint8_t byte = (state[i] >> (j * 8)) & 0xFF; ss << std::setw(2) << static_cast(byte); } } return ss.str(); } };