c++ - que - sacar el md5 de un archivo
¿Cómo obtener el hash MD5 de un archivo en C++? (12)
Aquí hay una implementación directa del comando md5sum
que calcula y muestra el MD5 del archivo especificado en la línea de comandos. Debe estar enlazado con la biblioteca OpenSSL ( gcc md5.c -o md5 -lssl
) para que funcione. Es C puro, pero debería ser capaz de adaptarlo a su aplicación C ++ con la suficiente facilidad.
#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;
}
Tengo la ruta del archivo. ¿Cómo puedo obtener el hash MD5?
Hay una bonita biblioteca en http://256stuff.com/sources/md5/ , con ejemplos de uso. Esta es la biblioteca más simple para MD5.
He usado Botan para realizar esta operación y otras antes. AraK ha señalado Crypto ++. Supongo que ambas bibliotecas son perfectamente válidas. Ahora depende de ti :-).
Necesitaba hacer esto ahora y necesitaba una solución multiplataforma que fuera adecuada para c ++ 11, boost y openssl. D''Nabre''s solución de D''Nabre''s como punto de partida y la D''Nabre''s a lo siguiente:
#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();
}
Un ejecutable de prueba rápida demuestra:
#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;
}
Algunas notas de enlace: Linux: -lcrypto -lboost_iostreams
Windows: -DBOOST_ALL_DYN_LINK libeay32.lib ssleay32.lib
Para cualquier persona que se redirija de " https://.com/questions/4393017/md5-implementation-in-c " porque se ha etiquetado incorrectamente como duplicado.
El ejemplo que se encuentra aquí funciona:
http://www.zedwood.com/article/cpp-md5-function
Si está compilando en VC ++ 2010, deberá cambiar su main.cpp a este:
#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;
}
Tendrá que cambiar ligeramente la clase MD5 si va a leer en una matriz char * en lugar de una cadena para responder la pregunta en esta página aquí.
EDITAR:
Aparentemente la modificación de la biblioteca MD5 no está clara, y una solución completa de VC ++ 2010 está aquí para su conveniencia para incluir char * ''s:
https://github.com/alm4096/MD5-Hash-Example-VS
Una pequeña explicación está aquí:
#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;
}
Simplemente agregué lo siguiente en la biblioteca MD5:
MD5.cpp:
MD5::MD5(char * Input, long length)
{
init();
update(Input, length);
finalize();
}
MD5.h:
std::string md5(char * Input, long length);
Puede implementar el algoritmo MD5 usted mismo (hay ejemplos en toda la web), o puede vincularlo con las librerías OpenSSL y usar las funciones resumidas de OpenSSL. aquí hay un ejemplo para obtener el MD5 de una matriz de bytes:
#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);
}
Una reelaboración de la impedancia de @ D''Nabre para C ++. No te olvides de compilar con -lcrypto al final: 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;
}
Usando Crypto ++, podrías hacer lo siguiente:
#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;
Necesito algo muy similar, porque no puedo leer en archivos de varios gigabytes solo para calcular un hash. En teoría, podría mapearlos en la memoria, pero tengo que admitir plataformas de 32 bits, eso todavía es problemático para archivos grandes.
Yo uso este archivo http://people.csail.mit.edu/rivest/Md5.c
La implementación de John Walker viene con sources .
md5.h
también tiene funciones MD5_*
muy útiles para archivos grandes
#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);
Muy simple, ¿no? Conversión a cadena también muy simple:
#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();
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
}