【发布时间】:2021-07-07 01:55:57
【问题描述】:
我试图通过读取文件的内容来创建文件的哈希值,然后使用SHA1 对其进行哈希处理,之后我试图用这个哈希值创建一个文件名,但问题只有哈希字符串的前两个字符是采取。
哈希函数
void hash(const std::string& content, std::string& retValue, bool isFile)
{
SHA_CTX ctx;
SHA1_Init(&ctx);
SHA1_Update(&ctx, content.c_str(), content.size());
if (isFile) {
FILE* f = fopen(content.c_str(),"r");
assert(f != NULL);
char buffer[1024]={0};
while(fgets(buffer,1024,f))
SHA1_Update(&ctx,buffer,strlen(buffer));
fclose(f);
}
unsigned char hash[SHA_DIGEST_LENGTH] = {0};
SHA1_Final(hash,&ctx);
retValue.resize(60);
int cnt = 0;
for(int i=0;i<SHA_DIGEST_LENGTH;i++){
char ch[3] = {0};
sprintf(ch,"%02x",hash[i]);
retValue[cnt++] = ch[0];
retValue[cnt++] = ch[1];
retValue[cnt++] = ch[2];
}
std::cout<<retValue<<std::endl;
}
当我在控制台中打印哈希值时,我得到了一个看起来有效的 val,例如 51d946cde43e90ec03493f88914ca948b5215916,但在这种情况下它只包含前两个字符“51”,我切换到 gdb 来查看字符串,gdb 向我显示以一种奇怪的方式字符串51\000d9\000\064\066\000cd\000e4\000\063e\000\071\060\000ec\000\060\063\000\064\071\000\063f\000\070\070\000\071\061\000\064c\000a9\000\064\070\000b5\000\062\06 1\000\065\071\000\061\066。我正在使用std::ofstream 保存文件。我已经查看了上一个答案,说这是 gdb 中的一个错误,所以它会像这样打印,但在这里我可以看到创建的文件不是只有第一个哈希字符。
为什么会这样?
谢谢。
- - - - - - - - - - - - - - - - - - - - - - - -编辑 - -------------------------------------------------- ---------------------
从 dvix 的评论中,它得到了解决,我正在用 ch[2] 复制 '\0',所以基本上我只需要从每个十六进制字符 ch[0] 和 ch[1] 复制前两个字符,然后放置null 在字符串的最后。
所以for循环里面的代码应该是这样的
for(int i=0;i<SHA_DIGEST_LENGTH;i++){
char ch[3] = {0};
sprintf(ch,"%02x",hash[i]);
retValue[cnt++] = ch[0];
retValue[cnt++] = ch[1];
}
retValue[cnt] = '\0';
【问题讨论】:
-
retValue[cnt++] = ch[2];这会在每 2 个十六进制字符后复制'\0'nul 终止符。但是您只希望字符串末尾的 nul 终止符。 -
负面选民应该评论他们在这方面的发现,所以我不再重复了。谢谢
-
@dxiv 好的,让我试试
-
@dxiv 感谢您的评论,它解决了我的问题 :)