首页 > 解决方案 > 在 C 中计算 MD5 - 将输出显示为字符串

问题描述

因此,我正在尝试使用 openssl 库在 C 中创建任意字符串的 MD5 哈希。这就是我到目前为止所做的:

#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>

void compute_md5(char *str, unsigned char digest[16]);

int main()
{
    unsigned char digest[16];
    compute_md5("hello world", digest);
    printf("%s", digest);
    return 0;
}

void compute_md5(char *str, unsigned char digest[16]) {
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, str, strlen(str));
    MD5_Final(digest, &ctx);
}

但是,输出中充满了不可打印的字符。如何正确将其显示为十六进制字符串?

标签: hashhexmd5

解决方案


你说得对,你不能printf("%s", digest);用来打印digest为字符串。请注意,这unsigned char digest[16];将是一个unsigned char 数组,不会被nul-terminated。您不能将其打印为字符串。而是将每个元素打印为带有 2 个字符的十六进制数字,例如

for (int i = 0; i < 16; i++)
    printf("%02x", digest[i]);
putchar ('\n');

您的完整示例将是:

#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>

void compute_md5(char *str, unsigned char digest[16]);

int main()
{
    unsigned char digest[16];
    compute_md5("hello world", digest);
    for (int i = 0; i < 16; i++)
        printf("%02x", digest[i]);
    putchar ('\n');
    return 0;
}

void compute_md5(char *str, unsigned char digest[16]) {
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, str, strlen(str));
    MD5_Final(digest, &ctx);
}

示例使用/输出

$ ./bin/md5openssl
5eb63bbbe01eeed093cb22bb8f5acdc3

创建一个字符串digest

如果您需要从中创建一个digest可以打印的字符串,那么您可以printf ("%s\n", buf);创建一个缓冲区,而不是将 2-char 十六进制表示形式写入stdout,用于sprintf将其写入缓冲区,对缓冲区进行 nul 终止,然后打印字符串。你可以这样做:

int main()
{
    unsigned char digest[16];
    char buf[sizeof digest * 2 + 1];
    compute_md5("hello world", digest);
    for (int i = 0, j = 0; i < 16; i++, j+=2)
        sprintf(buf+j, "%02x", digest[i]);
    buf[sizeof digest * 2] = 0;
    printf ("%s\n", buf);
    return 0;
}

(输出相同)

如果那不是您要找的,请告诉我。


推荐阅读