md5sum of file in Linux C

前端 未结 5 1987
时光取名叫无心
时光取名叫无心 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:13

    You can use the mhash library (license is LGPL). On Debian systems:

    sudo apt-get install libmhash-dev
    

    See the man page man 3 mhash

    But I don't think you can just give it the name of a file. You have to open the file yourself, read the data, and feed the data to this library's functions.

    0 讨论(0)
  • 2020-12-08 15:18

    You can use popen to run md5sum and read the output:

    #include <stdio.h>
    #include <ctype.h>
    
    #define STR_VALUE(val) #val
    #define STR(name) STR_VALUE(name)
    
    #define PATH_LEN 256
    #define MD5_LEN 32
    
    int CalcFileMD5(char *file_name, char *md5_sum)
    {
        #define MD5SUM_CMD_FMT "md5sum %." STR(PATH_LEN) "s 2>/dev/null"
        char cmd[PATH_LEN + sizeof (MD5SUM_CMD_FMT)];
        sprintf(cmd, MD5SUM_CMD_FMT, file_name);
        #undef MD5SUM_CMD_FMT
    
        FILE *p = popen(cmd, "r");
        if (p == NULL) return 0;
    
        int i, ch;
        for (i = 0; i < MD5_LEN && isxdigit(ch = fgetc(p)); i++) {
            *md5_sum++ = ch;
        }
    
        *md5_sum = '\0';
        pclose(p);
        return i == MD5_LEN;
    }
    
    int main(int argc, char *argv[])
    {
        char md5[MD5_LEN + 1];
    
        if (!CalcFileMD5("~/testfile", md5)) {
            puts("Error occured!");
        } else {
            printf("Success! MD5 sum is: %s\n", md5);
        }
    }
    
    0 讨论(0)
  • 2020-12-08 15:19

    There's code here.

    Also, the openssl libs have md5 functions (from here):

    #include <openssl/md5.h>
    #include <unistd.h>
    int main()
    {
        int n;
        MD5_CTX c;
        char buf[512];
        ssize_t bytes;
        unsigned char out[MD5_DIGEST_LENGTH];
    
        MD5_Init(&c);
        bytes=read(STDIN_FILENO, buf, 512);
        while(bytes > 0)
        {
            MD5_Update(&c, buf, bytes);
            bytes=read(STDIN_FILENO, buf, 512);
        }
    
        MD5_Final(out, &c);
    
        for(n=0; n<MD5_DIGEST_LENGTH; n++)
            printf("%02x", out[n]);
        printf("\n");
    
        return(0);        
    }
    
    0 讨论(0)
  • 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 <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>
    
    // 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;
    }
    
    0 讨论(0)
  • 2020-12-08 15:26

    An easy answer to the question asked by Raja and using answer from sje397, the md5sum of a file can be calculated within the C program as below. Also notice that there is no need of writing the read command twice when you can use the do while loop.

    int calculate_md5sum(char *filename)
    {
      //open file for calculating md5sum
      FILE *file_ptr;
      file_ptr = fopen(filename, "r");
      if (file_ptr==NULL)
      {
        perror("Error opening file");
        fflush(stdout);
        return 1;
      }
    
      int n;
      MD5_CTX c;
      char buf[512];
      ssize_t bytes;
      unsigned char out[MD5_DIGEST_LENGTH];
    
      MD5_Init(&c);
      do
      {
        bytes=fread(buf, 1, 512, file_ptr);
        MD5_Update(&c, buf, bytes);
      }while(bytes > 0);
    
      MD5_Final(out, &c);
    
      for(n=0; n<MD5_DIGEST_LENGTH; n++)
              printf("%02x", out[n]);
      printf("\n");
      return 0;
    }
    
    0 讨论(0)
提交回复
热议问题