经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
C++ 递归遍历文件并计算MD5的实例代码
来源:jb51  时间:2021/7/19 9:04:38  对本文有异议

递归遍历文件夹,对比文件md5

首先,需要引用 md5 的相关代码,参考这篇文章,防止链接内容被删除,这里再记录一次:

md5.h

  1. #ifndef MD5_H
  2. #define MD5_H
  3.  
  4. #include <string>
  5. #include <fstream>
  6.  
  7. /* Type define */
  8. typedef unsigned char byte;
  9. typedef unsigned int uint32;
  10.  
  11. using std::string;
  12. using std::ifstream;
  13.  
  14. /* MD5 declaration. */
  15. class MD5 {
  16. public:
  17. MD5();
  18. MD5(const void* input, size_t length);
  19. MD5(const string& str);
  20. MD5(ifstream& in);
  21. void update(const void* input, size_t length);
  22. void update(const string& str);
  23. void update(ifstream& in);
  24. const byte* digest();
  25. string toString();
  26. void reset();
  27.  
  28. private:
  29. void update(const byte* input, size_t length);
  30. void final();
  31. void transform(const byte block[64]);
  32. void encode(const uint32* input, byte* output, size_t length);
  33. void decode(const byte* input, uint32* output, size_t length);
  34. string bytesToHexString(const byte* input, size_t length);
  35.  
  36. /* class uncopyable */
  37. MD5(const MD5&);
  38. MD5& operator=(const MD5&);
  39.  
  40. private:
  41. uint32 _state[4]; /* state (ABCD) */
  42. uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */
  43. byte _buffer[64]; /* input buffer */
  44. byte _digest[16]; /* message digest */
  45. bool _finished; /* calculate finished ? */
  46.  
  47. static const byte PADDING[64]; /* padding for calculate */
  48. static const char HEX[16];
  49. enum { BUFFER_SIZE = 1024 };
  50. };
  51.  
  52. #endif /*MD5_H*/

md5.cpp

  1. #include "md5.h"
  2.  
  3. using namespace std;
  4.  
  5. /* Constants for MD5Transform routine. */
  6. #define S11 7
  7. #define S12 12
  8. #define S13 17
  9. #define S14 22
  10. #define S21 5
  11. #define S22 9
  12. #define S23 14
  13. #define S24 20
  14. #define S31 4
  15. #define S32 11
  16. #define S33 16
  17. #define S34 23
  18. #define S41 6
  19. #define S42 10
  20. #define S43 15
  21. #define S44 21
  22.  
  23.  
  24. /* F, G, H and I are basic MD5 functions.
  25. */
  26. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
  27. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  28. #define H(x, y, z) ((x) ^ (y) ^ (z))
  29. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  30.  
  31. /* ROTATE_LEFT rotates x left n bits.
  32. */
  33. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
  34.  
  35. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  36. Rotation is separate from addition to prevent recomputation.
  37. */
  38. #define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + ac; (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
  39. #define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + ac; (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
  40. #define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + ac; (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
  41. #define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + ac; (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
  42.  
  43.  
  44. const byte MD5::PADDING[64] = { 0x80 };
  45. const char MD5::HEX[16] = {
  46. 0‘, 1‘, 2‘, 3‘,
  47. 4‘, 5‘, 6‘, 7‘,
  48. 8‘, 9‘, a‘, b‘,
  49. c‘, d‘, e‘, f
  50. };
  51.  
  52.  
  53. /* Default construct. */
  54. MD5::MD5() {
  55. reset();
  56. }
  57.  
  58. /* Construct a MD5 object with a input buffer. */
  59. MD5::MD5(const void* input, size_t length) {
  60. reset();
  61. update(input, length);
  62. }
  63.  
  64. /* Construct a MD5 object with a string. */
  65. MD5::MD5(const string& str) {
  66. reset();
  67. update(str);
  68. }
  69.  
  70. /* Construct a MD5 object with a file. */
  71. MD5::MD5(ifstream& in) {
  72. reset();
  73. update(in);
  74. }
  75.  
  76. /* Return the message-digest */
  77. const byte* MD5::digest() {
  78.  
  79. if (!_finished) {
  80. _finished = true;
  81. final();
  82. }
  83. return _digest;
  84. }
  85.  
  86. /* Reset the calculate state */
  87. void MD5::reset() {
  88.  
  89. _finished = false;
  90. /* reset number of bits. */
  91. _count[0] = _count[1] = 0;
  92. /* Load magic initialization constants. */
  93. _state[0] = 0x67452301;
  94. _state[1] = 0xefcdab89;
  95. _state[2] = 0x98badcfe;
  96. _state[3] = 0x10325476;
  97. }
  98.  
  99. /* Updating the context with a input buffer. */
  100. void MD5::update(const void* input, size_t length) {
  101. update((const byte*)input, length);
  102. }
  103.  
  104. /* Updating the context with a string. */
  105. void MD5::update(const string& str) {
  106. update((const byte*)str.c_str(), str.length());
  107. }
  108.  
  109. /* Updating the context with a file. */
  110. void MD5::update(ifstream& in) {
  111.  
  112. if (!in) {
  113. return;
  114. }
  115.  
  116. std::streamsize length;
  117. char buffer[BUFFER_SIZE];
  118. while (!in.eof()) {
  119. in.read(buffer, BUFFER_SIZE);
  120. length = in.gcount();
  121. if (length > 0) {
  122. update(buffer, length);
  123. }
  124. }
  125. in.close();
  126. }
  127.  
  128. /* MD5 block update operation. Continues an MD5 message-digest
  129. operation, processing another message block, and updating the
  130. context.
  131. */
  132. void MD5::update(const byte* input, size_t length) {
  133.  
  134. uint32 i, index, partLen;
  135.  
  136. _finished = false;
  137.  
  138. /* Compute number of bytes mod 64 */
  139. index = (uint32)((_count[0] >> 3) & 0x3f);
  140.  
  141. /* update number of bits */
  142. if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) {
  143. ++_count[1];
  144. }
  145. _count[1] += ((uint32)length >> 29);
  146.  
  147. partLen = 64 - index;
  148.  
  149. /* transform as many times as possible. */
  150. if (length >= partLen) {
  151.  
  152. memcpy(&_buffer[index], input, partLen);
  153. transform(_buffer);
  154.  
  155. for (i = partLen; i + 63 < length; i += 64) {
  156. transform(&input[i]);
  157. }
  158. index = 0;
  159.  
  160. } else {
  161. i = 0;
  162. }
  163.  
  164. /* Buffer remaining input */
  165. memcpy(&_buffer[index], &input[i], length - i);
  166. }
  167.  
  168. /* MD5 finalization. Ends an MD5 message-_digest operation, writing the
  169. the message _digest and zeroizing the context.
  170. */
  171. void MD5::final() {
  172.  
  173. byte bits[8];
  174. uint32 oldState[4];
  175. uint32 oldCount[2];
  176. uint32 index, padLen;
  177.  
  178. /* Save current state and count. */
  179. memcpy(oldState, _state, 16);
  180. memcpy(oldCount, _count, 8);
  181.  
  182. /* Save number of bits */
  183. encode(_count, bits, 8);
  184.  
  185. /* Pad out to 56 mod 64. */
  186. index = (uint32)((_count[0] >> 3) & 0x3f);
  187. padLen = (index < 56) ? (56 - index) : (120 - index);
  188. update(PADDING, padLen);
  189.  
  190. /* Append length (before padding) */
  191. update(bits, 8);
  192.  
  193. /* Store state in digest */
  194. encode(_state, _digest, 16);
  195.  
  196. /* Restore current state and count. */
  197. memcpy(_state, oldState, 16);
  198. memcpy(_count, oldCount, 8);
  199. }
  200.  
  201. /* MD5 basic transformation. Transforms _state based on block. */
  202. void MD5::transform(const byte block[64]) {
  203.  
  204. uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16];
  205.  
  206. decode(block, x, 64);
  207.  
  208. /* Round 1 */
  209. FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
  210. FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
  211. FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
  212. FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
  213. FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
  214. FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
  215. FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
  216. FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
  217. FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
  218. FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
  219. FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  220. FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  221. FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  222. FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  223. FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  224. FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
  225.  
  226. /* Round 2 */
  227. GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
  228. GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
  229. GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  230. GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
  231. GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
  232. GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
  233. GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  234. GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
  235. GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
  236. GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  237. GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
  238. GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
  239. GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  240. GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
  241. GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
  242. GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
  243.  
  244. /* Round 3 */
  245. HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
  246. HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
  247. HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  248. HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  249. HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
  250. HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
  251. HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
  252. HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  253. HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  254. HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
  255. HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
  256. HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
  257. HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
  258. HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  259. HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  260. HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
  261.  
  262. /* Round 4 */
  263. II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
  264. II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
  265. II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  266. II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
  267. II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  268. II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
  269. II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  270. II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
  271. II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
  272. II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  273. II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
  274. II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  275. II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
  276. II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  277. II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
  278. II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
  279.  
  280. _state[0] += a;
  281. _state[1] += b;
  282. _state[2] += c;
  283. _state[3] += d;
  284. }
  285.  
  286. /* Encodes input (ulong) into output (byte). Assumes length is
  287. a multiple of 4.
  288. */
  289. void MD5::encode(const uint32* input, byte* output, size_t length) {
  290.  
  291. for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
  292. output[j]= (byte)(input[i] & 0xff);
  293. output[j + 1] = (byte)((input[i] >> 8) & 0xff);
  294. output[j + 2] = (byte)((input[i] >> 16) & 0xff);
  295. output[j + 3] = (byte)((input[i] >> 24) & 0xff);
  296. }
  297. }
  298.  
  299. /* Decodes input (byte) into output (ulong). Assumes length is
  300. a multiple of 4.
  301. */
  302. void MD5::decode(const byte* input, uint32* output, size_t length) {
  303.  
  304. for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
  305. output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) |
  306. (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24);
  307. }
  308. }
  309.  
  310. /* Convert byte array to hex string. */
  311. string MD5::bytesToHexString(const byte* input, size_t length) {
  312.  
  313. string str;
  314. str.reserve(length << 1);
  315. for (size_t i = 0; i < length; ++i) {
  316. int t = input[i];
  317. int a = t / 16;
  318. int b = t % 16;
  319. str.append(1, HEX[a]);
  320. str.append(1, HEX[b]);
  321. }
  322. return str;
  323. }
  324.  
  325. /* Convert digest to string value */
  326. string MD5::toString() {
  327. return bytesToHexString(digest(), 16);
  328. }

调用例子:

  1. #include "md5.h"
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. void PrintMD5(const string& str, MD5& md5) {
  7. cout << "MD5("" << str << "") = " << md5.toString() << endl;
  8. }
  9.  
  10. int main() {
  11.  
  12. MD5 md5;
  13. md5.update("");
  14. PrintMD5("", md5);
  15.  
  16. md5.update("a");
  17. PrintMD5("a", md5);
  18.  
  19. md5.update("bc");
  20. PrintMD5("abc", md5);
  21.  
  22. md5.update("defghijklmnopqrstuvwxyz");
  23. PrintMD5("abcdefghijklmnopqrstuvwxyz", md5);
  24.  
  25. md5.reset();
  26. md5.update("message digest");
  27. PrintMD5("message digest", md5);
  28.  
  29. md5.reset();
  30. md5.update(ifstream("D:\\test.txt"));
  31. PrintMD5("D:\\test.txt", md5);
  32.  
  33. return 0;
  34. }

配置好了以后开始写我们的递归遍历函数:

  1. /* 遍历目录下所有文件,对比 md5
  2. path:文件夹路径(末尾不要有‘\‘)
  3. format:要筛选的文件后缀名
  4. str_md5:md5 字符串
  5. isFound:是否匹配到与 str_md5 相等的 md5 值
  6. */
  7. void findAllFile_MD5(const char * path,const char * format,string str_md5,BOOL &isFound)
  8. {
  9. // 路径末尾追加 ‘\*.*‘
  10. char newpath[200];
  11. strcpy(newpath, path);
  12. strcat(newpath, "\\*.*");
  13. // 找到目录下的第一个文件 #include <io.h>
  14. _finddata_t findData;
  15. /* 文件信息结构体
  16. struct _finddata_t{
  17. unsigned attrib; // 文件属性
  18. time_t time_create; // 创建时的时间戳
  19. time_t time_access; // 最后一次被访问时的时间戳
  20. time_t time_write; // 最后一次被修改时的时间戳
  21. _fsize_t size; // 文件字节大小
  22. char name[_MAX_FNAME]; // 文件名
  23. };
  24. */
  25. long handle = _findfirst(newpath, &findData);
  26. if (handle == -1){return;}
  27. // 遍历文件和文件夹
  28. while (_findnext(handle, &findData) == 0){
  29. // 文件夹
  30. if (findData.attrib & _A_SUBDIR){
  31. // 文件夹名不能有敏感字符 ‘.‘、‘..‘
  32. if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0){continue;}
  33. // 进入这个文件夹继续遍历
  34. strcpy(newpath, path);
  35. strcat(newpath, "\\");
  36. strcat(newpath, findData.name);
  37. findAllFile_MD5(newpath,format,str_md5,isFound);
  38. }
  39. // 文件
  40. else{
  41. // 判断是不是指定后缀的文件
  42. if(strstr( findData.name,format)){
  43. // 输出(用来测试)
  44. //cout << "findData.size = " << findData.size << endl;
  45. //cout << "findData.name = " << findData.name << endl;
  46. //cout << "path = " << path << endl;
  47. // 取文件全路径
  48. string str_fullPath = path;
  49. str_fullPath+="\\"; str_fullPath+=findData.name;
  50.  
  51. // 取文件 md5,判断是否匹配特征
  52. MD5 md5;
  53. md5.reset();
  54. md5.update(ifstream(str_fullPath));
  55. if(md5.toString() == str_md5){isFound = TRUE;}
  56. }
  57. }
  58. }
  59.  
  60. // 关闭搜索句柄
  61. _findclose(handle);
  62. }

调用例子(遍历%temp% 下的文件)

  1. // 获取 %temp% 目录
  2. TCHAR lpTempPathBuffer[MAX_PATH];
  3. GetTempPath(MAX_PATH,lpTempPathBuffer);
  4.  
  5. // 删除末尾 ‘\‘
  6. string str_tempPath = lpTempPathBuffer;
  7. str_tempPath = str_tempPath.substr(0,str_tempPath.length()-1);
  8.  
  9. // 遍历目录下所有 exe 文件,匹配 MD5
  10. BOOL isFound = FALSE;
  11. findAllFile_MD5(stringToCharP(str_tempPath),".exe","52f5ce92c6f72c7e193b560bf4e76330",isFound);
  12. if(isFound){cout << "找到了!" << endl;;}

知识点扩展:

C++计算MD5

  1. #include "md5.h"
  2.  
  3. using namespace std;
  4.  
  5. /* Constants for MD5Transform routine. */
  6. #define S11 7
  7. #define S12 12
  8. #define S13 17
  9. #define S14 22
  10. #define S21 5
  11. #define S22 9
  12. #define S23 14
  13. #define S24 20
  14. #define S31 4
  15. #define S32 11
  16. #define S33 16
  17. #define S34 23
  18. #define S41 6
  19. #define S42 10
  20. #define S43 15
  21. #define S44 21
  22.  
  23.  
  24. /* F, G, H and I are basic MD5 functions.
  25. */
  26. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
  27. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  28. #define H(x, y, z) ((x) ^ (y) ^ (z))
  29. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  30.  
  31. /* ROTATE_LEFT rotates x left n bits.
  32. */
  33. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
  34.  
  35. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  36. Rotation is separate from addition to prevent recomputation.
  37. */
  38. #define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + ac; (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
  39. #define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + ac; (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
  40. #define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + ac; (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
  41. #define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + ac; (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
  42.  
  43.  
  44. const byte MD5::PADDING[64] = { 0x80 };
  45. const char MD5::HEX[16] = {
  46. '0', '1', '2', '3',
  47. '4', '5', '6', '7',
  48. '8', '9', 'a', 'b',
  49. 'c', 'd', 'e', 'f'
  50. };
  51.  
  52.  
  53. /* Default construct. */
  54. MD5::MD5() {
  55. reset();
  56. }
  57.  
  58. /* Construct a MD5 object with a input buffer. */
  59. MD5::MD5(const void* input, size_t length) {
  60. reset();
  61. update(input, length);
  62. }
  63.  
  64. /* Construct a MD5 object with a string. */
  65. MD5::MD5(const string& str) {
  66. reset();
  67. update(str);
  68. }
  69.  
  70. /* Construct a MD5 object with a file. */
  71. MD5::MD5(ifstream& in) {
  72. reset();
  73. update(in);
  74. }
  75.  
  76. /* Return the message-digest */
  77. const byte* MD5::digest() {
  78.  
  79. if (!_finished) {
  80. _finished = true;
  81. final();
  82. }
  83. return _digest;
  84. }
  85.  
  86. /* Reset the calculate state */
  87. void MD5::reset() {
  88.  
  89. _finished = false;
  90. /* reset number of bits. */
  91. _count[0] = _count[1] = 0;
  92. /* Load magic initialization constants. */
  93. _state[0] = 0x67452301;
  94. _state[1] = 0xefcdab89;
  95. _state[2] = 0x98badcfe;
  96. _state[3] = 0x10325476;
  97. }
  98.  
  99. /* Updating the context with a input buffer. */
  100. void MD5::update(const void* input, size_t length) {
  101. update((const byte*)input, length);
  102. }
  103.  
  104. /* Updating the context with a string. */
  105. void MD5::update(const string& str) {
  106. update((const byte*)str.c_str(), str.length());
  107. }
  108.  
  109. /* Updating the context with a file. */
  110. void MD5::update(ifstream& in) {
  111.  
  112. if (!in) {
  113. return;
  114. }
  115.  
  116. std::streamsize length;
  117. char buffer[BUFFER_SIZE];
  118. while (!in.eof()) {
  119. in.read(buffer, BUFFER_SIZE);
  120. length = in.gcount();
  121. if (length > 0) {
  122. update(buffer, length);
  123. }
  124. }
  125. in.close();
  126. }
  127.  
  128. /* MD5 block update operation. Continues an MD5 message-digest
  129. operation, processing another message block, and updating the
  130. context.
  131. */
  132. void MD5::update(const byte* input, size_t length) {
  133.  
  134. uint32 i, index, partLen;
  135.  
  136. _finished = false;
  137.  
  138. /* Compute number of bytes mod 64 */
  139. index = (uint32)((_count[0] >> 3) & 0x3f);
  140.  
  141. /* update number of bits */
  142. if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) {
  143. ++_count[1];
  144. }
  145. _count[1] += ((uint32)length >> 29);
  146.  
  147. partLen = 64 - index;
  148.  
  149. /* transform as many times as possible. */
  150. if (length >= partLen) {
  151.  
  152. memcpy(&_buffer[index], input, partLen);
  153. transform(_buffer);
  154.  
  155. for (i = partLen; i + 63 < length; i += 64) {
  156. transform(&input[i]);
  157. }
  158. index = 0;
  159.  
  160. }
  161. else {
  162. i = 0;
  163. }
  164.  
  165. /* Buffer remaining input */
  166. memcpy(&_buffer[index], &input[i], length - i);
  167. }
  168.  
  169. /* MD5 finalization. Ends an MD5 message-_digest operation, writing the
  170. the message _digest and zeroizing the context.
  171. */
  172. void MD5::final() {
  173.  
  174. byte bits[8];
  175. uint32 oldState[4];
  176. uint32 oldCount[2];
  177. uint32 index, padLen;
  178.  
  179. /* Save current state and count. */
  180. memcpy(oldState, _state, 16);
  181. memcpy(oldCount, _count, 8);
  182.  
  183. /* Save number of bits */
  184. encode(_count, bits, 8);
  185.  
  186. /* Pad out to 56 mod 64. */
  187. index = (uint32)((_count[0] >> 3) & 0x3f);
  188. padLen = (index < 56) ? (56 - index) : (120 - index);
  189. update(PADDING, padLen);
  190.  
  191. /* Append length (before padding) */
  192. update(bits, 8);
  193.  
  194. /* Store state in digest */
  195. encode(_state, _digest, 16);
  196.  
  197. /* Restore current state and count. */
  198. memcpy(_state, oldState, 16);
  199. memcpy(_count, oldCount, 8);
  200. }
  201.  
  202. /* MD5 basic transformation. Transforms _state based on block. */
  203. void MD5::transform(const byte block[64]) {
  204.  
  205. uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16];
  206.  
  207. decode(block, x, 64);
  208.  
  209. /* Round 1 */
  210. FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
  211. FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
  212. FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
  213. FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
  214. FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
  215. FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
  216. FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
  217. FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
  218. FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
  219. FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
  220. FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  221. FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  222. FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  223. FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  224. FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  225. FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
  226.  
  227. /* Round 2 */
  228. GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
  229. GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
  230. GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  231. GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
  232. GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
  233. GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
  234. GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  235. GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
  236. GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
  237. GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  238. GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
  239. GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
  240. GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  241. GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
  242. GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
  243. GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
  244.  
  245. /* Round 3 */
  246. HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
  247. HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
  248. HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  249. HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  250. HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
  251. HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
  252. HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
  253. HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  254. HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  255. HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
  256. HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
  257. HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
  258. HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
  259. HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  260. HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  261. HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
  262.  
  263. /* Round 4 */
  264. II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
  265. II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
  266. II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  267. II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
  268. II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  269. II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
  270. II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  271. II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
  272. II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
  273. II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  274. II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
  275. II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  276. II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
  277. II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  278. II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
  279. II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
  280.  
  281. _state[0] += a;
  282. _state[1] += b;
  283. _state[2] += c;
  284. _state[3] += d;
  285. }
  286.  
  287. /* Encodes input (ulong) into output (byte). Assumes length is
  288. a multiple of 4.
  289. */
  290. void MD5::encode(const uint32* input, byte* output, size_t length) {
  291.  
  292. for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
  293. output[j] = (byte)(input[i] & 0xff);
  294. output[j + 1] = (byte)((input[i] >> 8) & 0xff);
  295. output[j + 2] = (byte)((input[i] >> 16) & 0xff);
  296. output[j + 3] = (byte)((input[i] >> 24) & 0xff);
  297. }
  298. }
  299.  
  300. /* Decodes input (byte) into output (ulong). Assumes length is
  301. a multiple of 4.
  302. */
  303. void MD5::decode(const byte* input, uint32* output, size_t length) {
  304.  
  305. for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
  306. output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) |
  307. (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24);
  308. }
  309. }
  310.  
  311. /* Convert byte array to hex string. */
  312. string MD5::bytesToHexString(const byte* input, size_t length) {
  313.  
  314. string str;
  315. str.reserve(length << 1);
  316. for (size_t i = 0; i < length; ++i) {
  317. int t = input[i];
  318. int a = t / 16;
  319. int b = t % 16;
  320. str.append(1, HEX[a]);
  321. str.append(1, HEX[b]);
  322. }
  323. return str;
  324. }
  325.  
  326. /* Convert digest to string value */
  327. string MD5::toString() {
  328. return bytesToHexString(digest(), 16);
  329. }

到此这篇关于C++ 递归遍历文件并计算MD5的实例代码的文章就介绍到这了,更多相关C++ 递归遍历文件并计算MD5内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号