我正在尝试编写一个简单的哈希程序。这是代码:
#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()
可能不适合从文件中读取...
答案 0 :(得分:3)
我使用read()
代替fgets()
解决了这个问题:
while ((bytes = read(STDIN_FILENO, s, sizeof(s))) > 0)
{
EVP_DigestUpdate(ctx, s, bytes);
}
问题在于,尽管fgets()
将读取所有字节,但它不会返回读取的字节数,因此除非您知道输入的大小,否则无法可靠地确定缓冲区的相关程度提前。