C语言 Linux C 中文件的 md5sum

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3395690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:04:46  来源:igfitidea点击:

md5sum of file in Linux C

clinuxhashmd5

提问by Raja

I want to find md5sum of a file in Linux C, Is there any API where I can send file name to get md5sum of that file.

我想在 Linux C 中找到文件的 md5sum,是否有任何 API 可以发送文件名以获取该文件的 md5sum。

回答by sje397

There's code here.

有代码在这里

Also, the openssl libs have md5 functions (from here):

此外,openssl 库具有 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);        
}

回答by adf88

You can use popento run md5sumand read the output:

您可以使用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 = '
sudo apt-get install libmhash-dev
'; 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); } }

回答by Craig McQueen

You can use the mhashlibrary (license is LGPL). On Debian systems:

您可以使用mhash库(许可证是 LGPL)。在 Debian 系统上:

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

See the man page man 3 mhash

请参阅手册页 man 3 mhash

But I don't think you can just give it the name of a file. You have to open the file yourself, read the data, and feed the data to this library's functions.

但我不认为你可以只给它一个文件的名字。您必须自己打开文件,读取数据,并将数据提供给该库的函数。

回答by Shoaib Ahmed

If you're looking to generate MD5 hash for a file and compare it with a string, you can use this.

如果您想为文件生成 MD5 哈希并将其与字符串进行比较,则可以使用它。

Here, I have used D'Nabre's code from another SO answerand Michael Foukarakis's hex string to byte array code from this SO answer. It needs to be linked against the OpenSSL library (gcc md5.c -o md5 -lssl) to work.

在这里,我使用了来自另一个 SO answer 的 D'Nabre 代码来自这个 SO answer 的 Michael Fokarakis 的十六进制字符串到字节数组代码。它需要链接到 OpenSSL 库 (gcc md5.c -o md5 -lssl) 才能工作。

Sample usage:

示例用法:

#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.h:

md5.h:

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

md5.c:

md5.c:

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

回答by Mukund Madhusudan Atre

An easy answer to the question asked by Raja and using answer from sje397, the md5sum of a file can be calculated within the C program as below. Also notice that there is no need of writing the read command twice when you can use the do while loop.

对 Raja 提出的问题的简单回答并使用 sje397 的回答,文件的 md5sum 可以在 C 程序中计算如下。另请注意,当您可以使用 do while 循环时,无需两次写入读取命令。

##代码##