2010-08-03 37 views

Trả lời

32

Có mã here.

Ngoài ra, các libs openssl có chức năng md5 (từ 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

cảm ơn vì đã chia sẻ ví dụ ở đây! ('out' nên là một mảng' unsigned char' và length 'MD5_DIGEST_LENGTH'. Và cuối cùng' printf ("\ n"); 'tránh nhìn thấy các ký tự giả trên terminal của tôi.) –

+0

@Andre Holzner: Đã sửa lỗi. Chúc mừng. – sje397

+0

Khi chuyển đổi này để sử dụng một 'FILE' cho đầu vào, tôi đã phải sử dụng fread thay vì đọc, nếu không tôi đã nhận được một băm khác nhau – nmz787

12

Bạn có thể sử dụng popen để chạy md5sum và đọc kết quả:

#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

Bạn có thể sử dụng thư viện mhash (giấy phép là LGPL). Trên hệ thống Debian:

sudo apt-get install libmhash-dev 

Xem man page man 3 mhash

Nhưng tôi không nghĩ rằng bạn chỉ có thể cung cấp cho nó tên của một tập tin. Bạn phải tự mở tập tin, đọc dữ liệu và nạp dữ liệu vào các chức năng của thư viện này.

0

Nếu bạn đang tìm kiếm để tạo ra MD5 băm cho một tập tin và so sánh nó với một chuỗi, bạn có thể sử dụng điều này.

Ở đây, tôi đã sử dụng D'Nabre's code from another SO answerMichael Foukarakis's hex string to byte array code from this SO answer. Nó cần được liên kết với thư viện OpenSSL (gcc md5.c -o md5 -lssl) để hoạt động. sử dụng

mẫu:

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

Một câu trả lời đơn giản cho câu hỏi hỏi bởi Raja và sử dụng câu trả lời từ sje397 , md5sum của một tập tin có thể được tính toán trong chương trình C như sau. Cũng lưu ý rằng không cần phải viết lệnh đọc hai lần khi bạn có thể sử dụng vòng lặp while 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; 
} 
Các vấn đề liên quan