我有文件路径。我怎样才能获得它的MD5哈希值?
答案 0 :(得分:42)
这是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;
}
答案 1 :(得分:20)
您可以自己实现MD5算法(示例遍布Web),或者您可以链接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);
}
答案 2 :(得分:9)
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
}
答案 3 :(得分:7)
对于从“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);
答案 4 :(得分:7)
我现在需要这样做,并且需要一个适合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
答案 5 :(得分:4)
答案 6 :(得分:3)
之前我曾使用Botan执行此操作。 AraK指出了Crypto ++。我猜两个库都完全有效。现在取决于你: - )。
答案 7 :(得分:2)
http://256stuff.com/sources/md5/有一个漂亮的图书馆,有使用示例。这是MD5最简单的库。
答案 8 :(得分:2)
答案 9 :(得分:1)
使用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;
我需要一些非常相似的东西,因为我无法读取数千兆字节的文件来计算哈希值。从理论上讲,我可以将内存映射到它们,但我必须支持32位平台 - 这对于大型文件仍然存在问题。
答案 10 :(得分:1)
@ D&#39; Nabre对C ++的强制修改。不要忘记最后用-lcrypto编译:{{1}}。
gcc md5.c -o md5 -lcrypto
答案 11 :(得分:1)
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();