使用fgets

时间:2017-05-14 03:47:47

标签: c openssl fgets

我正在尝试编写一个简单的哈希程序。这是代码:

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

int main(int argc, char *argv[])
{
    unsigned char hash[EVP_MAX_MD_SIZE];
    unsigned hash_size;
    unsigned i;
    char s[100];

    EVP_MD_CTX *ctx = EVP_MD_CTX_create();
    EVP_MD_CTX_init(ctx);
    EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);

    while (fgets(s, sizeof(s), stdin))
    {
        EVP_DigestUpdate(ctx, s, strnlen(s, sizeof(s) - 1));
    }

    EVP_DigestFinal_ex(ctx, hash, &hash_size);
    EVP_MD_CTX_destroy(ctx);

    for (i = 0; i < hash_size; ++i)
    {
        printf("%02x", hash[i]);
    }

    printf("\n");

    EVP_MD_CTX_cleanup(ctx);
    return 0;
}

我使用以下21字节文件作为输入:

$ xxd testfile
0000000: 8c18 8425 ea30 2236 d472 47a0 38b9 003e  ...%.0"6.rG.8..>
0000010: 85ca 547e b1

不幸的是,我生成的SHA与sha1sum返回的内容不匹配:

$ sha1sum testfile
05a5e29ba59164ceee6bffbaec283ae5a6ecd66f  testfile
$ myhashprog < testfile
d8e5c7f4360beb2cabf7275d15293a711e5dfeb3

我做错了什么?

我注意到文件中有0x00看起来像字符串终止符,但我不知道如何处理它。在这种情况下,fgets()可能不适合从文件中读取...

1 个答案:

答案 0 :(得分:3)

我使用read()代替fgets()解决了这个问题:

while ((bytes = read(STDIN_FILENO, s, sizeof(s))) > 0)
{
    EVP_DigestUpdate(ctx, s, bytes);
}

问题在于,尽管fgets()将读取所有字节,但它不会返回读取的字节数,因此除非您知道输入的大小,否则无法可靠地确定缓冲区的相关程度提前。