Подтвердить что ты не робот

Md5sum файла в Linux C

Я хочу найти md5sum файла в Linux C, Есть ли какой-либо API, где я могу отправить имя файла, чтобы получить md5sum этого файла.

4b9b3361

Ответ 1

Здесь код здесь.

Кроме того, у opensl libs есть функции md5 (из здесь):

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

Ответ 2

Вы можете использовать popen для запуска md5sum и прочитать результат:

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

Ответ 3

Вы можете использовать библиотеку mhash (лицензия LGPL). В системах Debian:

sudo apt-get install libmhash-dev

См. справочную страницу man 3 mhash

Но я не думаю, что вы можете просто указать ему имя файла. Вам нужно открыть файл самостоятельно, прочитать данные и передать данные в функции этой библиотеки.

Ответ 4

Если вы хотите создать хэш MD5 для файла и сравнить его со строкой, вы можете использовать это.

Здесь я использовал код D'Nabre из другого ответа SO и Michael Foukarakis hex string для байтового массива из этот ответ SO. Он должен быть связан с библиотекой OpenSSL (gcc md5.c -o md5 -lssl) для работы.

Использование образца:

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

Ответ 5

Легкий ответ на вопрос, заданный Раджей и использование ответа от sje397, md5sum файла можно рассчитать в рамках программы C, как показано ниже. Также обратите внимание, что нет необходимости писать команду чтения дважды, когда вы можете использовать цикл 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;
}