如何在C++中获取文件的MD5哈希值?
z18hc3ub1#
下面是md5sum命令的直接实现,它计算并显示命令行上指定的文件的MD5。它需要链接到OpenSSL库(gcc md5.c -o md5 -lssl)才能工作。它是纯C语言,但您应该能够很容易地将其应用到C++应用程序中。
md5sum
gcc md5.c -o md5 -lssl
#include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/md5.h> unsigned char result[MD5_DIGEST_LENGTH]; // Print the MD5 sum as hex-digits. void print_md5_sum(unsigned char* md) { int i; for(i=0; i <MD5_DIGEST_LENGTH; i++) { printf("%02x",md[i]); } } // Get the size of the file by its file descriptor unsigned long get_size_by_fd(int fd) { struct stat statbuf; if(fstat(fd, &statbuf) < 0) exit(-1); return statbuf.st_size; } int main(int argc, char *argv[]) { int file_descript; unsigned long file_size; char* file_buffer; if(argc != 2) { printf("Must specify the file\n"); exit(-1); } printf("using file:\t%s\n", argv[1]); file_descript = open(argv[1], O_RDONLY); if(file_descript < 0) exit(-1); file_size = get_size_by_fd(file_descript); printf("file size:\t%lu\n", file_size); file_buffer = mmap(0, file_size, PROT_READ, MAP_SHARED, file_descript, 0); MD5((unsigned char*) file_buffer, file_size, result); munmap(file_buffer, file_size); print_md5_sum(result); printf(" %s\n", argv[1]); return 0; }
zour9fqk2#
您可以自己实现MD5算法(示例遍布网络),或者您可以链接OpenSSL库并使用OpenSSL的摘要函数。下面是一个获取字节数组的MD5的例子:
#include <openssl/md5.h> QByteArray AESWrapper::md5 ( const QByteArray& data) { unsigned char * tmp_hash; tmp_hash = MD5((const unsigned char*)data.constData(), data.length(), NULL); return QByteArray((const char*)tmp_hash, MD5_DIGEST_LENGTH); }
j5fpnvbx3#
对于任何从“https://stackoverflow.com/questions/4393017/md5-implementation-in-c”重定向的人,因为它被错误地标记为重复。这里的示例可以工作:http://www.zedwood.com/article/cpp-md5-function如果你在VC++2010中编译,那么你需要将他的main.cpp改为:
#include <iostream> //for std::cout #include <string.h> //for std::string #include "MD5.h" using std::cout; using std::endl; int main(int argc, char *argv[]) { std::string Temp = md5("The quick brown fox jumps over the lazy dog"); cout << Temp.c_str() << endl; return 0; }
如果你要读入一个char * 数组而不是一个字符串来回答这个页面上的问题,你将不得不稍微改变MD5类。编辑:显然,修改MD5库并不清楚,为了方便您,这里有一个完整的VC++2010解决方案,包括char *:https://github.com/alm4096/MD5-Hash-Example-VS这里有一点解释:
#include <iostream> //for std::cout #include <string.h> //for std::string #include <fstream> #include "MD5.h" using std::cout; using std::endl; int main(int argc, char *argv[]) { //Start opening your file ifstream inBigArrayfile; inBigArrayfile.open ("Data.dat", std::ios::binary | std::ios::in); //Find length of file inBigArrayfile.seekg (0, std::ios::end); long Length = inBigArrayfile.tellg(); inBigArrayfile.seekg (0, std::ios::beg); //read in the data from your file char * InFileData = new char[Length]; inBigArrayfile.read(InFileData,Length); //Calculate MD5 hash std::string Temp = md5(InFileData,Length); cout << Temp.c_str() << endl; //Clean up delete [] InFileData; return 0; }
我只是简单地将以下内容添加到MD5库中:MD5.cpp:
MD5::MD5(char * Input, long length) { init(); update(Input, length); finalize(); }
MD5.h:
std::string md5(char * Input, long length);
eni9jsuy4#
QFile file("bigimage.jpg"); if (file.open(QIODevice::ReadOnly)) { QByteArray fileData = file.readAll(); QByteArray hashData = QCryptographicHash::hash(fileData,QCryptographicHash::Md5); // or QCryptographicHash::Sha1 qDebug() << hashData.toHex(); // 0e0c2180dfd784dd84423b00af86e2fc }
rqdpfwrv5#
我现在需要这样做,需要一个适合c++11,boost和openssl的跨平台解决方案。我将D'Nabre's解决方案作为起点,并将其归结为以下内容:
#include <openssl/md5.h> #include <iomanip> #include <sstream> #include <boost/iostreams/device/mapped_file.hpp> const std::string md5_from_file(const std::string& path) { unsigned char result[MD5_DIGEST_LENGTH]; boost::iostreams::mapped_file_source src(path); MD5((unsigned char*)src.data(), src.size(), result); std::ostringstream sout; sout<<std::hex<<std::setfill('0'); for(auto c: result) sout<<std::setw(2)<<(int)c; return sout.str(); }
快速测试可执行文件演示了:
#include <iostream> int main(int argc, char *argv[]) { if(argc != 2) { std::cerr<<"Must specify the file\n"; exit(-1); } std::cout<<md5_from_file(argv[1])<<" "<<argv[1]<<std::endl; return 0; }
一些链接注解:Linux:-lcrypto -lboost_iostreams Windows:-DBOOST_ALL_DYN_LINK libeay32.lib ssleay32.lib
-lcrypto -lboost_iostreams
-DBOOST_ALL_DYN_LINK libeay32.lib ssleay32.lib
dddzy1tm6#
md5.h也有MD5_*功能,对于大文件非常有用
md5.h
MD5_*
#include <openssl/md5.h> #include <fstream> ....... std::ifstream file(filename, std::ifstream::binary); MD5_CTX md5Context; MD5_Init(&md5Context); char buf[1024 * 16]; while (file.good()) { file.read(buf, sizeof(buf)); MD5_Update(&md5Context, buf, file.gcount()); } unsigned char result[MD5_DIGEST_LENGTH]; MD5_Final(result, &md5Context);
很简单,不是吗?转换为字符串也很简单:
#include <sstream> #include <iomanip> ....... std::stringstream md5string; md5string << std::hex << std::uppercase << std::setfill('0'); for (const auto &byte: result) md5string << std::setw(2) << (int)byte; return md5string.str();
xwmevbvl7#
使用Crypto++,您可以执行以下操作:
#include <sha.h> #include <iostream> SHA256 sha; while ( !f.eof() ) { char buff[4096]; int numchars = f.read(...); sha.Update(buff, numchars); } char hash[size]; sha.Final(hash); cout << hash <<endl;
我需要非常类似的东西,因为我不能仅仅为了计算哈希而读取数GB的文件。理论上我可以Map它们,但是我必须支持32位平台--这对于大文件来说仍然是个问题。
dldeef678#
@ D 'Nabre为C++实现的一个返工。不要忘记在最后使用-lcrypto编译:gcc md5.c -o md5 -lcrypto .
gcc md5.c -o md5 -lcrypto
#include <iostream> #include <iomanip> #include <fstream> #include <string> #include <openssl/md5.h> using namespace std; unsigned char result[MD5_DIGEST_LENGTH]; // function to print MD5 correctly void printMD5(unsigned char* md, long size = MD5_DIGEST_LENGTH) { for (int i=0; i<size; i++) { cout<< hex << setw(2) << setfill('0') << (int) md[i]; } } int main(int argc, char *argv[]) { if(argc != 2) { cout << "Specify the file..." << endl; return 0; } ifstream::pos_type fileSize; char * memBlock; ifstream file (argv[1], ios::ate); //check if opened if (file.is_open() ) { cout<< "Using file\t"<< argv[1]<<endl; } else { cout<< "Unnable to open\t"<< argv[1]<<endl; return 0; } //get file size & copy file to memory //~ file.seekg(-1,ios::end); // exludes EOF fileSize = file.tellg(); cout << "File size \t"<< fileSize << endl; memBlock = new char[fileSize]; file.seekg(0,ios::beg); file.read(memBlock, fileSize); file.close(); //get md5 sum MD5((unsigned char*) memBlock, fileSize, result); //~ cout << "MD5_DIGEST_LENGTH = "<< MD5_DIGEST_LENGTH << endl; printMD5(result); cout<<endl; return 0; }
8条答案
按热度按时间z18hc3ub1#
下面是
md5sum
命令的直接实现,它计算并显示命令行上指定的文件的MD5。它需要链接到OpenSSL库(gcc md5.c -o md5 -lssl
)才能工作。它是纯C语言,但您应该能够很容易地将其应用到C++应用程序中。zour9fqk2#
您可以自己实现MD5算法(示例遍布网络),或者您可以链接OpenSSL库并使用OpenSSL的摘要函数。下面是一个获取字节数组的MD5的例子:
j5fpnvbx3#
对于任何从“https://stackoverflow.com/questions/4393017/md5-implementation-in-c”重定向的人,因为它被错误地标记为重复。
这里的示例可以工作:
http://www.zedwood.com/article/cpp-md5-function
如果你在VC++2010中编译,那么你需要将他的main.cpp改为:
如果你要读入一个char * 数组而不是一个字符串来回答这个页面上的问题,你将不得不稍微改变MD5类。
编辑:
显然,修改MD5库并不清楚,为了方便您,这里有一个完整的VC++2010解决方案,包括char *:
https://github.com/alm4096/MD5-Hash-Example-VS
这里有一点解释:
我只是简单地将以下内容添加到MD5库中:
MD5.cpp:
MD5.h:
eni9jsuy4#
rqdpfwrv5#
我现在需要这样做,需要一个适合c++11,boost和openssl的跨平台解决方案。我将D'Nabre's解决方案作为起点,并将其归结为以下内容:
快速测试可执行文件演示了:
一些链接注解:Linux:
-lcrypto -lboost_iostreams
Windows:-DBOOST_ALL_DYN_LINK libeay32.lib ssleay32.lib
dddzy1tm6#
md5.h
也有MD5_*
功能,对于大文件非常有用很简单,不是吗?转换为字符串也很简单:
xwmevbvl7#
使用Crypto++,您可以执行以下操作:
我需要非常类似的东西,因为我不能仅仅为了计算哈希而读取数GB的文件。理论上我可以Map它们,但是我必须支持32位平台--这对于大文件来说仍然是个问题。
dldeef678#
@ D 'Nabre为C++实现的一个返工。不要忘记在最后使用-lcrypto编译:
gcc md5.c -o md5 -lcrypto
.