2010-08-03 9 views

Répondre

32

Il y a le code here.

En outre, les bibliothèques OpenSSL ont des fonctions md5 (de 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

merci de partager l'exemple ici! ('out' devrait être un tableau de' unsigned char' et de la longueur 'MD5_DIGEST_LENGTH'. Et un' printf final ("\ n"); 'évite de voir des caractères parasites sur mon terminal.) –

+0

@Andre Holzner: Correction. À votre santé. – sje397

+0

Lors de la conversion pour utiliser un «FICHIER» pour la saisie, j'ai dû utiliser fread au lieu de lire, sinon je recevais un autre hachage – nmz787

12

Vous pouvez utiliser popen pour exécuter md5sum et lire la sortie:

#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

Vous pouvez utiliser la bibliothèque mhash (la licence est LGPL). Sur les systèmes Debian:

sudo apt-get install libmhash-dev 

Voir la page man man 3 mhash

Mais je ne pense pas que vous pouvez simplement lui donner le nom d'un fichier. Vous devez ouvrir le fichier vous-même, lire les données et envoyer les données aux fonctions de cette bibliothèque.

0

Si vous souhaitez générer un hachage MD5 pour un fichier et le comparer avec une chaîne, vous pouvez l'utiliser. Ici, j'ai utilisé D'Nabre's code from another SO answer et Michael Foukarakis's hex string to byte array code from this SO answer. Il doit être lié à la bibliothèque OpenSSL (gcc md5.c -o md5 -lssl) pour fonctionner.

Exemple d'utilisation:

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

Une réponse facile à la question posée par Raja et en utilisant réponse de sje397 , le md5sum d'un fichier peut être calculé dans le programme C comme ci-dessous. Notez également qu'il n'est pas nécessaire d'écrire deux fois la commande read lorsque vous pouvez utiliser la boucle 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; 
}