MD5的C++实现
2021/6/27 20:21:08
本文主要是介绍MD5的C++实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
放一波代码吧,MD5已经不是检查数据完整性的最佳选择了QAQ(但是有一定的教学意义)
基本原理网上都有,这份代码核心部分(压缩函数)也是从cryptopp搞来的,其他的填充啥的自己写的。就…称我为缝合怪吧hhh
注:由于填充过程是对整个数据读进内存然后进行的填充,所以计算大文件Hash时悠着点啊,内存炸了别赖我
md5.h
#ifndef MD5_H #define MD5_H #include<iostream> using namespace std; typedef unsigned int uint32; typedef unsigned char uint8; typedef unsigned long long uint64; #define F(b, c, d) ((b & c) | ((~b) & d)) #define G(b, c, d) ((b & d) | (c & (~d))) #define H(b, c, d) (b ^ c ^ d) #define I(b, c, d) (c ^ (b | ~d)) #define CLS(x, s) ((x << s)|(x >> (32 - s))) #define ROUND(f, w, x, y, z, data, s) \ w = CLS(w + f(x, y, z) + data, s) + x class MD5 { private: // 4 32-bit registers uint32 ctx[4] = { 0x67452301L,0xefcdab89L,0x98badcfeL,0x10325476L }; uint32* wordptr = NULL; uint8* byteptr = NULL; uint32 count = 0; // computer's endianess(little->false, big->true) bool endian = true;; public: MD5() { // test computer's endianess uint32 a = 0x01; uint8* b = (uint8*)&a; // set 'endian' flag if (*b == 0x01) { endian = false; } else if (*b == 0x00) { endian = true; } } void Load(uint8* data, uint64 len); void Transform(); string GetMD5Hash(uint8* data, uint64 size); string GetFileMD5Hash(string filename); }; #endif
md5.cpp
#include<iostream> #include<fstream> #include<math.h> #include<windows.h> #include"md5.h" #include"utils.h" void MD5::Load(uint8* data, uint64 size) { // get the length of data after padding uint64 bytelen = (size & 0x3f) < 56 ? (64 - (size & 0x3f) + size) : (64 - (size & 0x3f) + size + 64); // get the number of 512-bit blocks count = ceil((double)bytelen / 64); // create a new array wordptr = (uint32*)malloc(bytelen); if (wordptr != NULL) { byteptr = (uint8*)wordptr; // set zeros memset(wordptr, 0x00, bytelen); // copy 'data' to 'wordptr'/'byteptr' memcpy(byteptr, data, size); // add 0x80 *(byteptr + size) = 0x80; // add data's length if (endian == true) { // big-endian *(uint64*)(wordptr + bytelen / 4 - 2) = EndianTransfrom(size << 3); } else { // little-endian *(uint64*)(wordptr + bytelen / 4 - 2) = size << 3; } } return; } void MD5::Transform() { uint32 tmp, a, b, c, d; for (register int i = 0; i < count; i++) { int offset = i << 4; a = ctx[0]; b = ctx[1]; c = ctx[2]; d = ctx[3]; ROUND(F, a, b, c, d, wordptr[offset + 0] + 0xd76aa478, 7); ROUND(F, d, a, b, c, wordptr[offset + 1] + 0xe8c7b756, 12); ROUND(F, c, d, a, b, wordptr[offset + 2] + 0x242070db, 17); ROUND(F, b, c, d, a, wordptr[offset + 3] + 0xc1bdceee, 22); ROUND(F, a, b, c, d, wordptr[offset + 4] + 0xf57c0faf, 7); ROUND(F, d, a, b, c, wordptr[offset + 5] + 0x4787c62a, 12); ROUND(F, c, d, a, b, wordptr[offset + 6] + 0xa8304613, 17); ROUND(F, b, c, d, a, wordptr[offset + 7] + 0xfd469501, 22); ROUND(F, a, b, c, d, wordptr[offset + 8] + 0x698098d8, 7); ROUND(F, d, a, b, c, wordptr[offset + 9] + 0x8b44f7af, 12); ROUND(F, c, d, a, b, wordptr[offset + 10] + 0xffff5bb1, 17); ROUND(F, b, c, d, a, wordptr[offset + 11] + 0x895cd7be, 22); ROUND(F, a, b, c, d, wordptr[offset + 12] + 0x6b901122, 7); ROUND(F, d, a, b, c, wordptr[offset + 13] + 0xfd987193, 12); ROUND(F, c, d, a, b, wordptr[offset + 14] + 0xa679438e, 17); ROUND(F, b, c, d, a, wordptr[offset + 15] + 0x49b40821, 22); ROUND(G, a, b, c, d, wordptr[offset + 1] + 0xf61e2562, 5); ROUND(G, d, a, b, c, wordptr[offset + 6] + 0xc040b340, 9); ROUND(G, c, d, a, b, wordptr[offset + 11] + 0x265e5a51, 14); ROUND(G, b, c, d, a, wordptr[offset + 0] + 0xe9b6c7aa, 20); ROUND(G, a, b, c, d, wordptr[offset + 5] + 0xd62f105d, 5); ROUND(G, d, a, b, c, wordptr[offset + 10] + 0x02441453, 9); ROUND(G, c, d, a, b, wordptr[offset + 15] + 0xd8a1e681, 14); ROUND(G, b, c, d, a, wordptr[offset + 4] + 0xe7d3fbc8, 20); ROUND(G, a, b, c, d, wordptr[offset + 9] + 0x21e1cde6, 5); ROUND(G, d, a, b, c, wordptr[offset + 14] + 0xc33707d6, 9); ROUND(G, c, d, a, b, wordptr[offset + 3] + 0xf4d50d87, 14); ROUND(G, b, c, d, a, wordptr[offset + 8] + 0x455a14ed, 20); ROUND(G, a, b, c, d, wordptr[offset + 13] + 0xa9e3e905, 5); ROUND(G, d, a, b, c, wordptr[offset + 2] + 0xfcefa3f8, 9); ROUND(G, c, d, a, b, wordptr[offset + 7] + 0x676f02d9, 14); ROUND(G, b, c, d, a, wordptr[offset + 12] + 0x8d2a4c8a, 20); ROUND(H, a, b, c, d, wordptr[offset + 5] + 0xfffa3942, 4); ROUND(H, d, a, b, c, wordptr[offset + 8] + 0x8771f681, 11); ROUND(H, c, d, a, b, wordptr[offset + 11] + 0x6d9d6122, 16); ROUND(H, b, c, d, a, wordptr[offset + 14] + 0xfde5380c, 23); ROUND(H, a, b, c, d, wordptr[offset + 1] + 0xa4beea44, 4); ROUND(H, d, a, b, c, wordptr[offset + 4] + 0x4bdecfa9, 11); ROUND(H, c, d, a, b, wordptr[offset + 7] + 0xf6bb4b60, 16); ROUND(H, b, c, d, a, wordptr[offset + 10] + 0xbebfbc70, 23); ROUND(H, a, b, c, d, wordptr[offset + 13] + 0x289b7ec6, 4); ROUND(H, d, a, b, c, wordptr[offset + 0] + 0xeaa127fa, 11); ROUND(H, c, d, a, b, wordptr[offset + 3] + 0xd4ef3085, 16); ROUND(H, b, c, d, a, wordptr[offset + 6] + 0x04881d05, 23); ROUND(H, a, b, c, d, wordptr[offset + 9] + 0xd9d4d039, 4); ROUND(H, d, a, b, c, wordptr[offset + 12] + 0xe6db99e5, 11); ROUND(H, c, d, a, b, wordptr[offset + 15] + 0x1fa27cf8, 16); ROUND(H, b, c, d, a, wordptr[offset + 2] + 0xc4ac5665, 23); ROUND(I, a, b, c, d, wordptr[offset + 0] + 0xf4292244, 6); ROUND(I, d, a, b, c, wordptr[offset + 7] + 0x432aff97, 10); ROUND(I, c, d, a, b, wordptr[offset + 14] + 0xab9423a7, 15); ROUND(I, b, c, d, a, wordptr[offset + 5] + 0xfc93a039, 21); ROUND(I, a, b, c, d, wordptr[offset + 12] + 0x655b59c3, 6); ROUND(I, d, a, b, c, wordptr[offset + 3] + 0x8f0ccc92, 10); ROUND(I, c, d, a, b, wordptr[offset + 10] + 0xffeff47d, 15); ROUND(I, b, c, d, a, wordptr[offset + 1] + 0x85845dd1, 21); ROUND(I, a, b, c, d, wordptr[offset + 8] + 0x6fa87e4f, 6); ROUND(I, d, a, b, c, wordptr[offset + 15] + 0xfe2ce6e0, 10); ROUND(I, c, d, a, b, wordptr[offset + 6] + 0xa3014314, 15); ROUND(I, b, c, d, a, wordptr[offset + 13] + 0x4e0811a1, 21); ROUND(I, a, b, c, d, wordptr[offset + 4] + 0xf7537e82, 6); ROUND(I, d, a, b, c, wordptr[offset + 11] + 0xbd3af235, 10); ROUND(I, c, d, a, b, wordptr[offset + 2] + 0x2ad7d2bb, 15); ROUND(I, b, c, d, a, wordptr[offset + 9] + 0xeb86d391, 21); ctx[0] += a; ctx[1] += b; ctx[2] += c; ctx[3] += d; } } string MD5::GetMD5Hash(uint8* data, uint64 size) { Load(data, size); Transform(); free(byteptr); return bytesToHexString((uint8*)ctx, 16); } string MD5::GetFileMD5Hash(string filename) { // get file's size ifstream fin(filename, ios::in | ios::binary); fin.seekg(0, ios::end); uint64 size = fin.tellg(); fin.seekg(0, ios::beg); // initialize timer's variables LARGE_INTEGER cpuFreq, startTime, endTime; double runtime; QueryPerformanceFrequency(&cpuFreq); QueryPerformanceCounter(&startTime); // read data uint8* data = (uint8*)malloc(size); memset(data, 0, size); fin.read((char*)data, size); fin.close(); // compute hash and test md5's speed QueryPerformanceCounter(&startTime); string result = GetMD5Hash(data, size); QueryPerformanceCounter(&endTime); runtime = (((endTime.QuadPart - startTime.QuadPart) * 1.0f) / cpuFreq.QuadPart); printf("MD5 Speed: %lf MB/s\n", size * 1.0 / runtime / 1024 / 1024); free(data); return result; }
这篇关于MD5的C++实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-30uniAPP 实现全屏左右滚动滚动的效果-icode9专业技术文章分享
- 2024-06-30如何在本地使用授权或插件-icode9专业技术文章分享
- 2024-06-30伪静态规则配置方法汇总-icode9专业技术文章分享
- 2024-06-29易优CMS安装常见问题汇总-icode9专业技术文章分享
- 2024-06-28易优新手必读安装教程-icode9专业技术文章分享
- 2024-06-28忘记eyoucms后台密码怎么办?-icode9专业技术文章分享
- 2024-06-26终极指南:Scrum中如何设置需求优先级
- 2024-06-26AI大模型企业应用实战(25)-为Langchain Agent添加记忆功能
- 2024-06-26小白家庭 nas 搭建方案-icode9专业技术文章分享
- 2024-06-23AI大模型企业应用实战(14)-langchain的Embedding