it-swarm.com.de

mD5sum der Datei in Linux C

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

24
Raja

Es gibt Code hier .

Außerdem haben die openssl-Bibliotheken md5-Funktionen (von hier ):

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

Sie können popen verwenden, um md5sum auszuführen und die Ausgabe zu 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);
    }
}
12
adf88

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

Sudo apt-get install libmhash-dev

Siehe die Manpage man 3 mhash

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

3
Craig McQueen

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'Nabres Code aus einem anderen SO answer und Michael Foukarakis 'hex string aus einem Arraycode aus diesem SO answer . Sie muss mit der OpenSSL-Bibliothek (gcc md5.c -o md5 -lssl) verknüpft sein, damit sie funktioniert. 

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
Shoaib Ahmed

Eine einfache Antwort auf die von Raja gestellte Frage und die Antwort von sje397. Die MD5-Summe einer Datei kann im C-Programm wie folgt berechnet werden. Beachten Sie auch, dass Sie den read-Befehl 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;
}