对比文件MD5差异并保存

来源:互联网 发布:淘宝1元拍卖可信吗 编辑:程序博客网 时间:2024/05/14 18:08

参考

http://www.cnblogs.com/flying_bat/archive/2007/09/25/905133.html

http://www.cnblogs.com/Sniper-quay/archive/2011/04/23/2025643.html

http://www.2cto.com/kf/201501/367905.html

http://blog.csdn.net/hqw7286/article/details/5603442

http://jingyan.baidu.com/article/48b558e35d29c47f38c09a1f.html

http://www.cnblogs.com/luxiaoxun/archive/2012/08/03/2621803.html

http://www.cnblogs.com/TianFang/archive/2006/12/30/607859.html

http://blog.csdn.net/debugconsole/article/details/8677313

http://www.oschina.net/question/117937_146959

http://www.cnblogs.com/02xiaoma/archive/2012/07/18/2597576.html

http://www.cnblogs.com/ggjucheng/archive/2012/01/03/2311241.html

http://bbs.csdn.net/topics/80303224


以上参考资料中有部分MD5库有错(本人的测试结果,可能测试过程错误。错误结果是不同的两个文件,产生的MD5值是一样的)


以下是代码,代码中的MD5库是正确的(同样也是本人的测试结果,只供参考)

环境:vs2013


入口文件main

// updator.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h" //一定放在第一位载入#include<iostream>     #include<string>     #include<io.h>#include "MD5Hash.h"#include<stdio.h>#include<fstream>#include<map>#include<sstream>using namespace std;//文件格式struct updateRecord {string searchPath;//用于搜索和比较string filename;//文件名string md5str;//文件的md5码};//保存文本map<string, updateRecord> *data_;//对比时候使用map<string, updateRecord> *dataNew_;map<string, updateRecord> *dataOld_;//获取MD5字符串// void PrintMD5(const string &str, MD5 &md5) {// cout << "MD5(\"" << str << "\") = " << md5.toString() << endl;// }//截取路径string getNewPath(string str){int spos = (&str)->rfind("src/");if (spos < 1) {spos = (&str)->rfind("res/");}string newpath = "";if (spos > 0) {newpath = str.erase(0, spos);}return newpath;}//读取文件MD5值void readMD5(string fname, string fpath){// MD5 md5;// md5.reset();// md5.update(ifstream(fpath));//PrintMD5(fpath, md5);wstring md5wstr = CalcFileMD5(fpath);std::string md5str(md5wstr.length(), ' ');std::copy(md5wstr.begin(), md5wstr.end(), md5str.begin());updateRecord recod;recod.filename = fname;recod.md5str = md5str;recod.searchPath = getNewPath(fpath);data_->insert(make_pair(recod.searchPath, recod));}//扫描文件void visit(string path, int layer){struct _finddata_t   filefind;//string  curr = path + "\\*.*";string  curr = path + "/*.*";int   done = 0, i, handle;if ((handle = _findfirst(curr.c_str(), &filefind)) == -1)return;while (!(done = _findnext(handle, &filefind))){//printf("%s\n", filefind.name);if (!strcmp(filefind.name, "..") || !strcmp(filefind.name, ".") || !strcmp(filefind.name, ".svn")){continue;}for (i = 0; i < layer; i++)cout << "     ";if ((_A_SUBDIR == filefind.attrib)) //是目录  {printf("----------%s\n", filefind.name);//cout << filefind.name << "(dir)" << endl;curr = path + "/" + filefind.name;visit(curr, 1);continue;}else//不是目录,是文件       {string filepath = path + "/" + filefind.name;printf("\n========== %s", filepath.c_str());//cout << path + "\\" + filefind.name << endl;readMD5(filefind.name, filepath);}}printf("\n");_findclose(handle);}//保存日志void saveTxt(string path, string name, map<string, updateRecord> *dmap){cout << "******** 打印保存文件 **********" << endl;//日志打开路径string fp = path + "/" + name;ofstream in;in.open(fp, ios::trunc);//打开该文件,没有则创建。并清空map<string, updateRecord>::iterator it = dmap->begin();for (it; it != dmap->end(); it++) {updateRecord m = it->second;//按照搜索路径,文件名,MD5码顺序保存in << m.searchPath << "\t" << m.filename << "\t" << m.md5str << "\t";cout << m.searchPath << "\t" << m.filename << "\t" << m.md5str << "\n" << endl;}in.close();}//功能1,保存文件MD5值void function1(){data_->clear();//扫描文件string path; // = "d:/server/k7android"cout << "请输入目录(符号/)" << endl;cin >> path;visit(path, 1);//保存日志string txtPath;cout << "请输入日志保存路径(符号/)" << endl;cin >> txtPath;string txtName;cout << "请输入日志名(**.txt)" << endl;cin >> txtName;saveTxt(txtPath, txtName, data_);}//---------------------------------------以上功能1----------------------------------------------------//读取文件数据//path日志打开路径bool readTxt(map<string, updateRecord> *data, string path){char buffer[256];data->clear();fstream out;out.open(path, ios::in);if (!out) {cout << "打开文件:" << path << "  失败!!!" << endl;return false;}while (!out.eof()) {updateRecord recod;//按照搜索路径,文件名,MD5码顺序读取for (int i = 0; i < 3; i++) {if (!out.eof()) {out.getline(buffer, 10000, '\t');//getline(char *,int,char) 表示该行字符达到10000个或遇到tab就结束//cout << buffer << endl;/*if (i == 0) {//字串转数字int num;stringstream ss((string)buffer);ss >> num;cout << "num: " << num << endl;recod.num = num;}*/if (i == 0) {string searchPath = (string)buffer;cout << "searchPath: " << searchPath << endl;recod.searchPath = searchPath;}else if (i == 1) {string filename = (string)buffer;cout << "filename: " << filename << endl;recod.filename = filename;}else if (i == 2) {string md5str = (string)buffer;cout << "md5: " << md5str << endl;recod.md5str = md5str;}}else {switch (i){//case 0: recod.num = 0; break;case 0: recod.searchPath = ""; break;case 1: recod.filename = ""; break;case 2: recod.md5str = ""; break;default:break;}}}//fordata->insert(make_pair(recod.searchPath, recod));}return true;}//比较两个文件void compareTxt(string newTxtName){map<string, updateRecord> *updateData = new map<string, updateRecord>();//拿新的和旧的比map<string, updateRecord>::iterator itNew = dataNew_->begin();//遍历新的文件for (itNew; itNew != dataNew_->end(); itNew++) {updateRecord rnew = itNew->second;string sp = rnew.searchPath;updateRecord rold;map<string, updateRecord>::iterator itOld = dataOld_->find(sp);//旧文件中有的,新文件没有的不需要查询if (itOld == dataOld_->end()) {//在旧文件中没找到,说明这个是新加文件。视为差异文件,需要被保存updateData->insert(make_pair(rnew.searchPath, rnew));}else {rold = itOld->second;if (rnew.md5str != rold.md5str) {//新文件的MD5值和旧文件的MD5值不同,说明被改动。视为差异文件,需要被保存updateData->insert(make_pair(rnew.searchPath, rnew));}}}//保存差异文件string savePath;cout << "输入差异文件列表保存路径(符号/)" << endl;cin >> savePath;string newName = "diff_" + newTxtName;saveTxt(savePath, newName, updateData);}//返回 1相同  2不同  3不能比较int compare2(string pnew, string pold) {char buffernew[256];fstream outnew;outnew.open(pnew, ios::in);if (!outnew) {cout << "打开新文件:" << pnew << "  失败!!!" << endl;return 3;}char bufferold[256];fstream outold;outold.open(pold, ios::in);if (!outold) {cout << "打开旧文件:" << pold << "  失败!!!" << endl;return 2;}while (!outnew.eof()) {outnew.getline(buffernew, 10000, '\n');if (!outold.eof()) {outold.getline(bufferold, 10000, '\n');if ((string)buffernew != (string)bufferold) {return 2;}}else {//不同return 2;}}return 1;}void visit2(string pathnew, string pathold){int layerNew = 1;struct _finddata_t   filefind;//string  curr = path + "\\*.*";string  curr = pathnew + "/*.*";int   done = 0, i, handle;if ((handle = _findfirst(curr.c_str(), &filefind)) == -1)return;while (!(done = _findnext(handle, &filefind))){//printf("%s\n", filefind.name);if (!strcmp(filefind.name, "..") || !strcmp(filefind.name, ".") || !strcmp(filefind.name, ".svn")){continue;}for (i = 0; i < layerNew; i++)cout << "     ";if ((_A_SUBDIR == filefind.attrib)) //是目录  {printf("----------%s\n", filefind.name);//cout << filefind.name << "(dir)" << endl;curr = pathnew + "/" + filefind.name;visit2(curr, pathold);continue;}else//不是目录,是文件       {string curr = pathnew + "/" + filefind.name;string fileNewPath = curr;//oldpathint spos = (&curr)->rfind("src/");if (spos < 1) {spos = (&curr)->rfind("res/");}string newpath = "";if (spos > 0) {newpath = curr.erase(0, spos);}string fileOldPath = pathold + "/" + newpath;printf("\n newpath========== %s", fileNewPath.c_str());printf("\n oldpath========== %s", fileOldPath.c_str());//cout << path + "\\" + filefind.name << endl;//readMD5(filefind.name, filepath);int ret = compare2(fileNewPath, fileOldPath);//1相同  2不同  3不能比较if (ret == 1) {cout << "文件相同:" << filefind.name << endl;}else if (ret == 2) {cout << "文件不同:" << filefind.name << endl;}else if (ret == 3) {cout << "两个文件不能比较!!!" << endl;}else {cout << "对比出错啦!!!" << endl;}}}printf("\n");_findclose(handle);}//功能2,对比MD5文件void function2(){string fn1;cout << "输入较新文件的名字(*.txt)" << endl;cin >> fn1;string fp1;cout << "输入较新文件的路径(符号/)" << endl;cin >> fp1;string fn2;cout << "输入较旧文件的名字(*.txt)" << endl;cin >> fn2;string fp2;cout << "输入较旧文件的路径(符号/)" << endl;cin >> fp2;//读取文件数据string f1 = fp1 + "/" + fn1;string f2 = fp2 + "/" + fn2;bool openSuccess = true;openSuccess = readTxt(dataNew_, f1);if (openSuccess)openSuccess = readTxt(dataOld_, f2);//对比文件数据,获取差异文件if (openSuccess)compareTxt(fn1);//全文件对比//visit2(fp1, fp2);}//功能选择int chooseFunc(){string func;cout << "选择功能:1读取并保存文件MD5;2对比两个文件差异;3结束" << endl;cin >> func;int funcn;stringstream ss(func);ss >> funcn;return funcn;}//入口int _tmain(int argc, _TCHAR* argv[]){printf("\n hello!!!\n");//定义数据表data_ = new map<string, updateRecord>();dataNew_ = new map<string, updateRecord>();dataOld_ = new map<string, updateRecord>();//功能选择int funcn = chooseFunc();while (funcn==1 || funcn == 2){if (funcn == 1) {cout << "功能1-------保存文件MD5\n" << endl;function1();}else if (funcn == 2) {cout << "功能2-------对比两个md5文件差异\n" << endl;function2();}/*else if (funcn == 3) {cout << "----test----\n" << endl;}*/funcn = chooseFunc();}return 0;}

MD5Has.h

#pragma once#include <string>using std::wstring;using namespace std;#ifndef ULONGtypedef unsigned long ULONG;#endif#ifndef UINTtypedef unsigned int UINT;#endif#define MD5FILE 1#define MD5STRING 2wstring CalcMD5(int i_type, string lpcw_str);wstring CalcFileMD5(string file_path);wstring CalcStringMD5(int i_type, string str_name);/* Data structure for MD5 (Message Digest) computation */typedef struct {ULONG i[2];                   /* Number of _bits_ handled mod 2^64 */ULONG buf[4];                                    /* Scratch buffer */wchar_t in[64];                              /* Input buffer */wchar_t digest[16];     /* Actual digest after MD5Final call */} MD5_CTX;class MD5Hash{public:MD5Hash(void);~MD5Hash(void);void MD5_Transform(ULONG *buf, ULONG *in);void MD5Init(MD5_CTX *mdContext, ULONG pseudoRandomNumber = 0);void MD5Update(MD5_CTX *mdContext, wchar_t *inBuf, UINT inLen);void MD5Final(MD5_CTX *mdContext);int md5file(const wchar_t *fn , ULONG seed , MD5_CTX *mdContext) ;};


MD5Hash.cpp

#include "StdAfx.h"#include "MD5Hash.h"wstring CalcMD5(int i_type, string lpcw_str){wstring result;if (i_type == MD5FILE) {}return 0;}wstring CalcFileMD5(string file_path){MD5Hash m_md5;MD5_CTX m_md5_ctx;wstring result;wchar_t tmp[3];FILE *fileToHash = NULL;//wstring fileName = file_path;std::wstring fileName(file_path.length(), L' ');std::copy(file_path.begin(), file_path.end(), fileName.begin());if(fileName.empty()) {return _T("");}if(m_md5.md5file(fileName.c_str(), 0, &m_md5_ctx)) {for(int i = 0; i < 16; i++) {//_itoa(m_md5_ctx.digest[i], tmp, 16);_itow_s(m_md5_ctx.digest[i], tmp, 16);if(wcsnlen_s(tmp, 3) == 1) {tmp[1] = tmp[0];tmp[0] = '0';tmp[2] = '\0';}result += tmp;}}return result;}wstring CalcStringMD5(int i_type, string str_name){return 0;}MD5Hash::MD5Hash(void){}MD5Hash::~MD5Hash(void){}/* Padding */static wchar_t MD5_PADDING[64] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};/* MD5_F, MD5_G and MD5_H are basic MD5 functions: selection, majority, parity */#define MD5_F(x, y, z) (((x) & (y)) | ((~x) & (z)))#define MD5_G(x, y, z) (((x) & (z)) | ((y) & (~z)))#define MD5_H(x, y, z) ((x) ^ (y) ^ (z))#define MD5_I(x, y, z) ((y) ^ ((x) | (~z)))/* ROTATE_LEFT rotates x left n bits */#ifndef ROTATE_LEFT#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))#endif/* MD5_FF, MD5_GG, MD5_HH, and MD5_II transformations for rounds 1, 2, 3, and 4 *//* Rotation is separate from addition to prevent recomputation */#define MD5_FF(a, b, c, d, x, s, ac) {(a) += MD5_F ((b), (c), (d)) + (x) + (ULONG)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }#define MD5_GG(a, b, c, d, x, s, ac) {(a) += MD5_G ((b), (c), (d)) + (x) + (ULONG)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }#define MD5_HH(a, b, c, d, x, s, ac) {(a) += MD5_H ((b), (c), (d)) + (x) + (ULONG)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }#define MD5_II(a, b, c, d, x, s, ac) {(a) += MD5_I ((b), (c), (d)) + (x) + (ULONG)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }/* Constants for transformation */#define MD5_S11 7  /* Round 1 */#define MD5_S12 12#define MD5_S13 17#define MD5_S14 22#define MD5_S21 5  /* Round 2 */#define MD5_S22 9#define MD5_S23 14#define MD5_S24 20#define MD5_S31 4  /* Round 3 */#define MD5_S32 11#define MD5_S33 16#define MD5_S34 23#define MD5_S41 6  /* Round 4 */#define MD5_S42 10#define MD5_S43 15#define MD5_S44 21void MD5Hash::MD5_Transform( ULONG *buf, ULONG *in ){ULONG a = buf[0], b = buf[1], c = buf[2], d = buf[3];/* Round 1 */MD5_FF ( a, b, c, d, in[ 0], MD5_S11, (ULONG) 3614090360u); /* 1 */MD5_FF ( d, a, b, c, in[ 1], MD5_S12, (ULONG) 3905402710u); /* 2 */MD5_FF ( c, d, a, b, in[ 2], MD5_S13, (ULONG)  606105819u); /* 3 */MD5_FF ( b, c, d, a, in[ 3], MD5_S14, (ULONG) 3250441966u); /* 4 */MD5_FF ( a, b, c, d, in[ 4], MD5_S11, (ULONG) 4118548399u); /* 5 */MD5_FF ( d, a, b, c, in[ 5], MD5_S12, (ULONG) 1200080426u); /* 6 */MD5_FF ( c, d, a, b, in[ 6], MD5_S13, (ULONG) 2821735955u); /* 7 */MD5_FF ( b, c, d, a, in[ 7], MD5_S14, (ULONG) 4249261313u); /* 8 */MD5_FF ( a, b, c, d, in[ 8], MD5_S11, (ULONG) 1770035416u); /* 9 */MD5_FF ( d, a, b, c, in[ 9], MD5_S12, (ULONG) 2336552879u); /* 10 */MD5_FF ( c, d, a, b, in[10], MD5_S13, (ULONG) 4294925233u); /* 11 */MD5_FF ( b, c, d, a, in[11], MD5_S14, (ULONG) 2304563134u); /* 12 */MD5_FF ( a, b, c, d, in[12], MD5_S11, (ULONG) 1804603682u); /* 13 */MD5_FF ( d, a, b, c, in[13], MD5_S12, (ULONG) 4254626195u); /* 14 */MD5_FF ( c, d, a, b, in[14], MD5_S13, (ULONG) 2792965006u); /* 15 */MD5_FF ( b, c, d, a, in[15], MD5_S14, (ULONG) 1236535329u); /* 16 *//* Round 2 */MD5_GG ( a, b, c, d, in[ 1], MD5_S21, (ULONG) 4129170786u); /* 17 */MD5_GG ( d, a, b, c, in[ 6], MD5_S22, (ULONG) 3225465664u); /* 18 */MD5_GG ( c, d, a, b, in[11], MD5_S23, (ULONG)  643717713u); /* 19 */MD5_GG ( b, c, d, a, in[ 0], MD5_S24, (ULONG) 3921069994u); /* 20 */MD5_GG ( a, b, c, d, in[ 5], MD5_S21, (ULONG) 3593408605u); /* 21 */MD5_GG ( d, a, b, c, in[10], MD5_S22, (ULONG)   38016083u); /* 22 */MD5_GG ( c, d, a, b, in[15], MD5_S23, (ULONG) 3634488961u); /* 23 */MD5_GG ( b, c, d, a, in[ 4], MD5_S24, (ULONG) 3889429448u); /* 24 */MD5_GG ( a, b, c, d, in[ 9], MD5_S21, (ULONG)  568446438u); /* 25 */MD5_GG ( d, a, b, c, in[14], MD5_S22, (ULONG) 3275163606u); /* 26 */MD5_GG ( c, d, a, b, in[ 3], MD5_S23, (ULONG) 4107603335u); /* 27 */MD5_GG ( b, c, d, a, in[ 8], MD5_S24, (ULONG) 1163531501u); /* 28 */MD5_GG ( a, b, c, d, in[13], MD5_S21, (ULONG) 2850285829u); /* 29 */MD5_GG ( d, a, b, c, in[ 2], MD5_S22, (ULONG) 4243563512u); /* 30 */MD5_GG ( c, d, a, b, in[ 7], MD5_S23, (ULONG) 1735328473u); /* 31 */MD5_GG ( b, c, d, a, in[12], MD5_S24, (ULONG) 2368359562u); /* 32 *//* Round 3 */MD5_HH ( a, b, c, d, in[ 5], MD5_S31, (ULONG) 4294588738u); /* 33 */MD5_HH ( d, a, b, c, in[ 8], MD5_S32, (ULONG) 2272392833u); /* 34 */MD5_HH ( c, d, a, b, in[11], MD5_S33, (ULONG) 1839030562u); /* 35 */MD5_HH ( b, c, d, a, in[14], MD5_S34, (ULONG) 4259657740u); /* 36 */MD5_HH ( a, b, c, d, in[ 1], MD5_S31, (ULONG) 2763975236u); /* 37 */MD5_HH ( d, a, b, c, in[ 4], MD5_S32, (ULONG) 1272893353u); /* 38 */MD5_HH ( c, d, a, b, in[ 7], MD5_S33, (ULONG) 4139469664u); /* 39 */MD5_HH ( b, c, d, a, in[10], MD5_S34, (ULONG) 3200236656u); /* 40 */MD5_HH ( a, b, c, d, in[13], MD5_S31, (ULONG)  681279174u); /* 41 */MD5_HH ( d, a, b, c, in[ 0], MD5_S32, (ULONG) 3936430074u); /* 42 */MD5_HH ( c, d, a, b, in[ 3], MD5_S33, (ULONG) 3572445317u); /* 43 */MD5_HH ( b, c, d, a, in[ 6], MD5_S34, (ULONG)   76029189u); /* 44 */MD5_HH ( a, b, c, d, in[ 9], MD5_S31, (ULONG) 3654602809u); /* 45 */MD5_HH ( d, a, b, c, in[12], MD5_S32, (ULONG) 3873151461u); /* 46 */MD5_HH ( c, d, a, b, in[15], MD5_S33, (ULONG)  530742520u); /* 47 */MD5_HH ( b, c, d, a, in[ 2], MD5_S34, (ULONG) 3299628645u); /* 48 *//* Round 4 */MD5_II ( a, b, c, d, in[ 0], MD5_S41, (ULONG) 4096336452u); /* 49 */MD5_II ( d, a, b, c, in[ 7], MD5_S42, (ULONG) 1126891415u); /* 50 */MD5_II ( c, d, a, b, in[14], MD5_S43, (ULONG) 2878612391u); /* 51 */MD5_II ( b, c, d, a, in[ 5], MD5_S44, (ULONG) 4237533241u); /* 52 */MD5_II ( a, b, c, d, in[12], MD5_S41, (ULONG) 1700485571u); /* 53 */MD5_II ( d, a, b, c, in[ 3], MD5_S42, (ULONG) 2399980690u); /* 54 */MD5_II ( c, d, a, b, in[10], MD5_S43, (ULONG) 4293915773u); /* 55 */MD5_II ( b, c, d, a, in[ 1], MD5_S44, (ULONG) 2240044497u); /* 56 */MD5_II ( a, b, c, d, in[ 8], MD5_S41, (ULONG) 1873313359u); /* 57 */MD5_II ( d, a, b, c, in[15], MD5_S42, (ULONG) 4264355552u); /* 58 */MD5_II ( c, d, a, b, in[ 6], MD5_S43, (ULONG) 2734768916u); /* 59 */MD5_II ( b, c, d, a, in[13], MD5_S44, (ULONG) 1309151649u); /* 60 */MD5_II ( a, b, c, d, in[ 4], MD5_S41, (ULONG) 4149444226u); /* 61 */MD5_II ( d, a, b, c, in[11], MD5_S42, (ULONG) 3174756917u); /* 62 */MD5_II ( c, d, a, b, in[ 2], MD5_S43, (ULONG)  718787259u); /* 63 */MD5_II ( b, c, d, a, in[ 9], MD5_S44, (ULONG) 3951481745u); /* 64 */buf[0] += a;buf[1] += b;buf[2] += c;buf[3] += d;}void MD5Hash::MD5Init( MD5_CTX *mdContext, ULONG pseudoRandomNumber /*= 0*/ ){mdContext->i[0] = mdContext->i[1] = (ULONG)0;/* Load magic initialization constants */mdContext->buf[0] = (ULONG)0x67452301 + (pseudoRandomNumber * 11);mdContext->buf[1] = (ULONG)0xefcdab89 + (pseudoRandomNumber * 71);mdContext->buf[2] = (ULONG)0x98badcfe + (pseudoRandomNumber * 37);mdContext->buf[3] = (ULONG)0x10325476 + (pseudoRandomNumber * 97);}void MD5Hash::MD5Update( MD5_CTX *mdContext, wchar_t *inBuf, UINT inLen ){ULONG in[16];int mdi = 0;unsigned int i = 0, ii = 0;/* Compute number of bytes mod 64 */mdi = (int)((mdContext->i[0] >> 3) & 0x3F);/* Update number of bits */if ((mdContext->i[0] + ((ULONG)inLen << 3)) < mdContext->i[0]) {mdContext->i[1]++;}mdContext->i[0] += ((ULONG)inLen << 3);mdContext->i[1] += ((ULONG)inLen >> 29);while (inLen--) {/* Add new character to buffer, increment mdi */mdContext->in[mdi++] = *inBuf++;/* Transform if necessary */if (mdi == 0x40) {for (i = 0, ii = 0; i < 16; i++, ii += 4)in[i] = (((ULONG)mdContext->in[ii + 3]) << 24) |        (((ULONG)mdContext->in[ii + 2]) << 16) |        (((ULONG)mdContext->in[ii + 1]) << 8) |        ((ULONG)mdContext->in[ii]);MD5_Transform (mdContext->buf, in);mdi = 0;}}}void MD5Hash::MD5Final( MD5_CTX *mdContext ){ULONG in[16];int mdi = 0;unsigned int i = 0, ii = 0, padLen = 0;/* Save number of bits */in[14] = mdContext->i[0];in[15] = mdContext->i[1];/* Compute number of bytes mod 64 */mdi = (int)((mdContext->i[0] >> 3) & 0x3F);/* Pad out to 56 mod 64 */padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);MD5Update (mdContext, MD5_PADDING, padLen);/* Append length in bits and transform */for (i = 0, ii = 0; i < 14; i++, ii += 4)in[i] = (((ULONG)mdContext->in[ii + 3]) << 24) |        (((ULONG)mdContext->in[ii + 2]) << 16) |        (((ULONG)mdContext->in[ii + 1]) <<  8) |        ((ULONG)mdContext->in[ii]);MD5_Transform (mdContext->buf, in);/* Store buffer in digest */for (i = 0, ii = 0; i < 4; i++, ii += 4) {mdContext->digest[ii]   = (unsigned char)( mdContext->buf[i]        & 0xFF);mdContext->digest[ii + 1] = (unsigned char)((mdContext->buf[i] >>  8) & 0xFF);mdContext->digest[ii + 2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);mdContext->digest[ii + 3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);}}int MD5Hash::md5file( const wchar_t *fn , ULONG seed , MD5_CTX *mdContext ){ULONG size = 0;FILE *f;_wfopen_s(&f, fn, _T("rb"));if(f == NULL) {return 0 ;}MD5Init(mdContext , seed) ;wchar_t buf[2048] ;UINT trb = 0 ;for(;;) {int rb = fread(buf , 1 , 2048 , f) ;if(size > 0 && rb + trb > size) {rb = size - trb ;}trb += rb ;MD5Update(mdContext , buf , rb) ;if(rb < 2048 || (size > 0 && trb >= size)) {break ;}}fclose(f) ;MD5Final(mdContext) ;return trb ;}

工程下载:http://download.csdn.net/detail/c471961491/8815687

0 0
原创粉丝点击