2010-08-03 9 views
22

Ich möchte md5sum einer Datei in Linux C finden, Gibt es eine API, wo ich Dateinamen senden kann, um MD5sum dieser Datei zu erhalten.md5sum der Datei in Linux C

Antwort

32

Es gibt Code here.

Auch haben die OpenSSL-Libs md5 Funktionen (von 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);   
} 
+1

danke für das Teilen des Beispiels hier! ('out' sollte ein Array von' unsigned char' und Länge 'MD5_DIGEST_LENGTH' sein. Und ein abschließender' printf ("\ n"); 'vermeidet das Aufspüren falscher Zeichen auf meinem Terminal.) –

+0

@Andre Holzner: Fixed. Prost. – sje397

+0

Wenn ich dies umwandelte, um eine 'FILE' für die Eingabe zu verwenden, musste ich fread anstelle von read verwenden, sonst bekam ich einen anderen Hash – nmz787

12

können Sie popen verwenden md5sum laufen zu lassen und die Ausgabe lesen:

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

Sie können die mhash Bibliothek verwenden (Lizenz ist LGPL). Auf Debian-Systemen:

sudo apt-get install libmhash-dev 

Siehe Manpage man 3 mhash

Aber ich glaube nicht, können Sie es nur den Namen einer Datei geben. Sie müssen die Datei selbst öffnen, die Daten lesen und die Daten den Funktionen dieser Bibliothek zuführen.

0

Wenn Sie MD5-Hash für eine Datei generieren und mit einer Zeichenfolge vergleichen möchten, können Sie dies verwenden.

Hier habe ich D'Nabre's code from another SO answer und Michael Foukarakis's hex string to byte array code from this SO answer verwendet. Es muss mit der OpenSSL-Bibliothek (gcc md5.c -o md5-lssl) verknüpft werden, um zu funktionieren.

Verwendungsbeispiel:

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

Eine einfache Antwort auf die Frage von Raja gefragt und mit Antwort von sje397 kann die md5sum einer Datei innerhalb des C-Programms wie folgt berechnet werden. Beachten Sie auch, dass Sie den Lesebefehl nicht zweimal schreiben müssen, wenn Sie die do while-Schleife verwenden können.

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; 
}