md5sum of file in Linux C

前端 未结 5 1988
时光取名叫无心
时光取名叫无心 2020-12-08 15:01

I want to find md5sum of a file in Linux C, Is there any API where I can send file name to get md5sum of that file.

5条回答
  •  一生所求
    2020-12-08 15:23

    If you're looking to generate MD5 hash for a file and compare it with a string, you can use this.

    Here, I have used D'Nabre's code from another SO answer and Michael Foukarakis's hex string to byte array code from this SO answer. It needs to be linked against the OpenSSL library (gcc md5.c -o md5 -lssl) to work.

    Sample usage:

    unsigned char *file_hash = md5_for_file("~/testfile");
    if (md5_is_match_str(file_hash, "b7be4ec867f9b0286b91dd40178774d6")) {
        printf("Match\n");
    } else {
        printf("Mismatch\n");
    }
    
    free(file_hash);
    

    md5.h:

    #ifndef MD5_H
    #define MD5_H
    
    /** Caller to free result */
    unsigned char *md5_for_file(char *filename);
    
    /** md5_1 & md5_2 maybe NULL */
    int md5_is_match(unsigned char *md5_1, unsigned char *md5_2);
    
    /** md5 maybe NULL */
    int md5_is_match_str(unsigned char *md5, const char *md5_str);
    
    #endif //MD5_H
    

    md5.c:

    #include "md5.h"
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    // 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]);
        }
        printf("\n");
    }
    
    // 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;
    }
    
    unsigned char *md5_for_file(char *filename) {
        int file_descript;
        unsigned long file_size;
        char *file_buffer;
        unsigned char *result = malloc(sizeof(*result) * MD5_DIGEST_LENGTH);
        if (NULL == result) {
            printf("malloc failed\n");
            goto END;
        }
    
        printf("using file:\t%s\n", filename);
    
        file_descript = open(filename, 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);
        END:
        return result;
    }
    
    int md5_is_match(unsigned char *md5_1, unsigned char *md5_2) {
        if (!md5_1 || !md5_2) {
            return 0;
        }
    
        int i;
        for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
            if (md5_1[i] != md5_2[i]) {
                return 0;
            }
        }
    
        return 1;
    }
    
    int md5_is_match_str(unsigned char *md5, char *md5_str) {
        if (!md5 || !md5_str) { return 0; }
    
        /** Make byte arrary from md5_str */
        unsigned char md5_arr[MD5_DIGEST_LENGTH] = {0};
    
        const char *pos = md5_str;
        size_t count = 0;
    
        /* WARNING: no sanitization or error-checking whatsoever */
        for (count = 0; count < sizeof(md5_arr) / sizeof(md5_arr[0]); count++) {
            sscanf(pos, "%2hhx", &md5_arr[count]);
            pos += 2;
        }
    
        for (count = 0; count < sizeof(md5_arr) / sizeof(md5_arr[0]); count++) {
            printf("%02x", md5_arr[count]);
        }
        printf("\n");
    
        /** actual comparison */
        if (memcmp(md5, md5_arr, MD5_DIGEST_LENGTH)) {
            return 0;
        }
    
        return 1;
    }
    

提交回复
热议问题