首页 文章

如何在C中获取文件的MD5哈希? [关闭]

提问于
浏览
65

我有文件路径 . 我怎样才能获得它的MD5哈希值?

12 回答

  • 1
  • 4

    我现在需要这样做,需要一个适合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

  • 41

    @D 'Nabre for C++. Don't的修复工作的遗留工作忘了在最后使用-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;
    }
    
  • 2

    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();
    
  • 2
  • 7

    我之前使用了Botan来执行此操作 . AraK指出了Crypto . 我猜两个库都完全有效 . 现在取决于你:-) .

  • 20

    使用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位平台 - 这对于大型文件仍然存在问题 .

  • 3

    您可以自己实现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);
    }
    
  • 1

    对于从“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库并不清楚,Full 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);
    
  • 1

    这是 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;
    }
    
  • 4
    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
    
    }
    
  • 9

    http://256stuff.com/sources/md5/有一个漂亮的图书馆,有使用的例子 . 这是MD5最简单的库 .

相关问题