如何在 C++ 中获取文件的 MD5 哈希值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1220046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the MD5 hash of a file in C++?
提问by user145586
I've the file path. How can I get the MD5 hash of it?
我有文件路径。我怎样才能得到它的 MD5 哈希值?
回答by D'Nabre
Here's a straight forward implementation of the md5sum
command that computes and displays the MD5 of the file specified on the command-line. It needs to be linked against the OpenSSL library (gcc md5.c -o md5 -lssl
) to work. It's pure C, but you should be able to adapt it to your C++ application easily enough.
这是该md5sum
命令的直接实现,用于计算和显示在命令行上指定的文件的 MD5。它需要链接到 OpenSSL 库 ( gcc md5.c -o md5 -lssl
) 才能工作。它是纯 C 语言,但您应该能够很容易地将其调整到您的 C++ 应用程序中。
#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;
}
回答by OneOfOne
You can implement the MD5 algorithm yourself (examples are all over the web), or you can link against the OpenSSL libs and use OpenSSL's digest functions. here's an example to get the MD5 of a byte array:
您可以自己实现 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);
}
回答by iyiy
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
}
回答by Benedict
I needed to do this just now and required a cross-platform solution that was suitable for c++11, boost and openssl. I took D'Nabre'ssolution as a starting point and boiled it down to the following:
我刚刚需要这样做,并且需要一个适用于 c++11、boost 和 openssl 的跨平台解决方案。我以D'Nabre 的解决方案为起点,将其归结为以下几点:
#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();
}
A quick test executable demonstrates:
一个快速测试可执行文件演示:
#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;
}
Some linking notes:
Linux: -lcrypto -lboost_iostreams
Windows: -DBOOST_ALL_DYN_LINK libeay32.lib ssleay32.lib
一些链接说明:Linux:-lcrypto -lboost_iostreams
Windows:-DBOOST_ALL_DYN_LINK libeay32.lib ssleay32.lib
回答by ALM865
For anyone redirected from "https://stackoverflow.com/questions/4393017/md5-implementation-in-c" because it's been incorrectly labelled a duplicate.
对于从“ https://stackoverflow.com/questions/4393017/md5-implementation-in-c”重定向的任何人,因为它被错误地标记为重复。
The example located here works:
位于此处的示例有效:
http://www.zedwood.com/article/cpp-md5-function
http://www.zedwood.com/article/cpp-md5-function
If you are compiling in VC++2010 then you will need to change his main.cpp to this:
如果您在 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;
}
You will have to change the MD5 class slightly if you are to read in a char * array instead of a string to answer the question on this page here.
如果您要读取 char * 数组而不是字符串来回答此页面上的问题,则必须稍微更改 MD5 类。
EDIT:
编辑:
Apparently modifying the MD5 library isn't clear, well a Full VC++2010 solution is here for your convenience to include char *'s:
显然修改 MD5 库不清楚,为了您的方便,这里有一个完整的 VC++2010 解决方案,包括字符 *:
https://github.com/alm4096/MD5-Hash-Example-VS
https://github.com/alm4096/MD5-Hash-Example-VS
A bit of an explanation is here:
这里有一点解释:
#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;
}
I have simply added the following into the MD5 library:
我只是将以下内容添加到 MD5 库中:
MD5.cpp:
MD5.cpp:
MD5::MD5(char * Input, long length)
{
init();
update(Input, length);
finalize();
}
MD5.h:
MD5.h:
std::string md5(char * Input, long length);
回答by Ulterior
I use this file http://people.csail.mit.edu/rivest/Md5.c
回答by javier-sanz
回答by user176443
There is a pretty library at http://256stuff.com/sources/md5/, with example of use. This is the simplest library for MD5.
http://256stuff.com/sources/md5/有一个漂亮的库,有使用示例。这是最简单的 MD5 库。
回答by Chris K
Using Crypto++, you could do the following:
使用 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;
I have a need for something very similar, because I can't read in multi-gigabyte files just to compute a hash. In theory I could memory map them, but I have to support 32bit platforms - that's still problematic for large files.
我需要一些非常相似的东西,因为我不能仅仅为了计算哈希而读取多 GB 的文件。理论上我可以对它们进行内存映射,但我必须支持 32 位平台——这对于大文件来说仍然是有问题的。
回答by Alessandro Jacopson
John Walker's implementationcomes with sources.