2010-08-03 12 views
22

Voglio trovare md5sum di un file in Linux C, C'è qualche API in cui posso inviare il nome del file per ottenere md5sum di quel file.md5sum di file in Linux C

risposta

32

C'è il codice here.

Inoltre, le librerie OpenSSL hanno funzioni md5 (da 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

grazie per aver condiviso l'esempio qui! ('out' dovrebbe essere un array di' char unsigned 'e lunghezza 'MD5_DIGEST_LENGTH'. E un finale' printf ("\ n"); 'evita di vedere caratteri spuri sul mio terminale.) –

+0

@Andre Holzner: risolto. Saluti. – sje397

+0

Quando si converte questo per usare un 'FILE' per l'input, ho dovuto usare fread invece di leggere, altrimenti stavo ottenendo un hash diverso – nmz787

12

È possibile utilizzare popen per eseguire md5sum e leggere l'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); 
    } 
} 
2

È possibile utilizzare la libreria mhash (la licenza è LGPL). Sui sistemi Debian:

sudo apt-get install libmhash-dev 

vedere la pagina man man 3 mhash

Ma non credo che si può solo dare il nome di un file. Devi aprire tu stesso il file, leggere i dati e inserire i dati nelle funzioni di questa libreria.

0

Se si sta cercando di generare un hash MD5 per un file e confrontarlo con una stringa, è possibile utilizzarlo.

Qui, ho usato D'Nabre's code from another SO answer e Michael Foukarakis's hex string to byte array code from this SO answer. Per funzionare deve essere collegato alla libreria OpenSSL (gcc md5.c -o md5 -lssl). utilizzo

Esempio:

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

Una risposta semplice alla domanda posta da Raja e con risposta da sje397 , il md5sum di un file può essere calcolato all'interno del programma C come sotto. Si noti inoltre che non è necessario scrivere il comando di lettura due volte quando è possibile utilizzare il ciclo do while.

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