C 使用fgets时,哈希与sha1sum不同
我正在尝试编写一个简单的哈希程序。代码如下:C 使用fgets时,哈希与sha1sum不同,c,openssl,fgets,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
#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;
}
不幸的是,我生成的SHA与sha1sum
返回的内容不匹配:
$ sha1sum testfile
05a5e29ba59164ceee6bffbaec283ae5a6ecd66f testfile
$ myhashprog < testfile
d8e5c7f4360beb2cabf7275d15293a711e5dfeb3
$sha1sum测试文件
05A5E29BA59164CEEE6BFBAEC283AE5A6ECD66F测试文件
$myhashprog
我做错了什么
我注意到文件中有一个
0x00
,看起来像字符串终止符,但我不确定如何处理它。可能fgets()
在这种情况下不是从文件中读取的合适函数…我通过使用read()
而不是fgets()
解决了这个问题:
问题是,尽管
fgets()
将读取所有字节,但它不会返回读取的字节数,因此除非您事先知道输入的大小,否则无法可靠地确定缓冲区的相关大小。是的,不要使用fgets,只需读取原始字节(您已经知道文件大小对应的字节数).如果它是从管子里出来的呢?那么你必须一直读下去,直到你得到“流的尽头”。您可以分块更新摘要,无需一次将其全部读入内存。无论哪种方式,读取原始字节。不要对零字节进行特殊处理。使用read()
效果很好。由于没有正式答案,我倾向于删除这个问题。有人介意吗?@Stephen-我建议把这个问题留待讨论。我快速搜索了一个副本,但没有找到。此外,有人可能会对使用EVP\u MD\u CTX\u destroy
和EVP\u MD\u CTX\u cleanup
发表评论。我认为一个是超级的,但是我手头没有源代码可以检查。如果没有答案,也许你可以提供一个正式的答案。它可能会对未来的访问者有所帮助。这里最突出的一点是,fgets
想要读取字符串,并在零字节处停止<代码>读取将读取尽可能多的字节。谢谢,我已经更新了我的答案,使其更全面。
$ sha1sum testfile
05a5e29ba59164ceee6bffbaec283ae5a6ecd66f testfile
$ myhashprog < testfile
d8e5c7f4360beb2cabf7275d15293a711e5dfeb3
while ((bytes = read(STDIN_FILENO, s, sizeof(s))) > 0)
{
EVP_DigestUpdate(ctx, s, bytes);
}