Como obter o hash MD5 de um arquivo em C ++?

Eu tenho o caminho do arquivo. Como posso obter o hash MD5 dele?

Aqui está uma implementação direta do comando md5sum que calcula e exibe o MD5 do arquivo especificado na linha de comando. Ele precisa estar vinculado à biblioteca do OpenSSL ( gcc md5.c -o md5 -lssl ) para funcionar. É puro C, mas você deve ser capaz de adaptá-lo ao seu aplicativo C ++ com bastante facilidade.

 #include  #include  #include  #include  #include  #include  #include  #include  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  

Você pode implementar o algoritmo MD5 você mesmo (os exemplos estão em toda a web), ou você pode se ligar às bibliotecas OpenSSL e usar as funções digest do OpenSSL. aqui está um exemplo para obter o MD5 de uma matriz de bytes:

 #include  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); } 
 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 } 

Para qualquer pessoa redirecionada de ” https://stackoverflow.com/questions/4393017/md5-implementation-in-c ” porque está incorretamente rotulada como duplicada.

O exemplo localizado aqui funciona:

http://www.zedwood.com/article/cpp-md5-function

Se você está compilando em VC ++ 2010, então você precisará alterar seu main.cpp para isso:

 #include  //for std::cout #include  //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; } 

Você terá que alterar um pouco a class MD5 se quiser ler em uma matriz char * em vez de uma string para responder a pergunta nesta página aqui.

EDITAR:

Aparentemente modificar a biblioteca MD5 não está claro, bem, uma solução Full VC ++ 2010 está aqui para sua conveniência include char * 's:

https://github.com/alm4096/MD5-Hash-Example-VS

Um pouco de explicação está aqui:

 #include  //for std::cout #include  //for std::string #include  #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; } 

Eu simplesmente adicionei o seguinte na biblioteca MD5:

MD5.cpp:

 MD5::MD5(char * Input, long length) { init(); update(Input, length); finalize(); } 

MD5.h:

 std::string md5(char * Input, long length); 

Eu precisava fazer isso agora e precisava de uma solução de plataforma cruzada que fosse adequada para c ++ 11, boost e openssl. Tomei a solução da D’Nabre como ponto de partida e resumi o seguinte:

 #include  #include  #include  #include  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<  

Um teste rápido executável demonstra:

 #include  int main(int argc, char *argv[]) { if(argc != 2) { std::cerr< <"Must specify the file\n"; exit(-1); } std::cout< 

Algumas notas de binding: Linux: -lcrypto -lboost_iostreams Windows: -DBOOST_ALL_DYN_LINK libeay32.lib ssleay32.lib

Eu usei Botan para realizar esta operação e outros antes. AraK apontou o Crypto ++. Eu acho que ambas as bibliotecas são perfeitamente válidas. Agora cabe a você :-).

A implementação de John Walker vem com fonts .

Há uma biblioteca bonita em http://256stuff.com/sources/md5/ , com exemplo de uso. Esta é a biblioteca mais simples para o MD5.

Usando o Crypto ++, você poderia fazer o seguinte:

 #include  #include  SHA256 sha; while ( !f.eof() ) { char buff[4096]; int numchars = f.read(...); sha.Update(buff, numchars); } char hash[size]; sha.Final(hash); cout < < hash < 

Eu tenho uma necessidade de algo muito semelhante, porque eu não posso ler em arquivos multi-gigabyte apenas para calcular um hash. Em teoria, eu poderia mapeá-los na memory, mas tenho que suportar plataformas de 32 bits - isso ainda é problemático para arquivos grandes.

Um retrabalho de impementação por @ D’Nabre para C ++. Não esqueça de compilar com -lcrypto no final: gcc md5.c -o md5 -lcrypto .

 #include  #include  #include  #include  #include  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
		      	

md5.h também tem funções MD5_* muito úteis para arquivos grandes

 #include  #include  ....... 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); 

Muito simples, não é? Conversão para string também é muito simples:

 #include  #include  ....... 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();