C语言中输入相同ID多次SHA1哈希结果不一致的问题求助
问题分析与修复方案
你遇到的问题根源非常明确——你调用SHA1函数时传入的输入长度参数错误,导致哈希计算包含了未初始化的垃圾内存数据,进而每次得到不同的结果。
具体问题点
在sha1_hash函数中,你写了:
SHA1(input_url, 160, hashed_160bits);
这里的第二个参数是要哈希的字节长度,但你固定传了160,而不是输入字符串的实际长度。你用malloc分配了1024字节的内存,但输入的ID长度肯定远小于160,剩下的内存空间是未初始化的垃圾数据(每次运行可能不一样)。SHA1会把这些随机的垃圾数据也纳入计算,所以即使输入的ID相同,最终的哈希值也会不同。第三次偶然结果一致只是巧合。
修复步骤
- 修正SHA1的长度参数:把固定的
160改成strlen(input_url),这样只计算输入字符串的有效长度。 - 可选:初始化分配的内存:为了避免其他潜在的未初始化内存问题,建议在
malloc后用memset把内存清零,不过这不是解决当前问题的必须步骤,但能让代码更健壮。
修改后的完整代码
#include <stdio.h> #include <string.h> #include <openssl/sha.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> char *sha1_hash(char *input_url, char *hashed_url) { unsigned char hashed_160bits[20]; char hashed_hex[41]; int i; // 修正:使用输入字符串的实际长度作为SHA1的输入长度 SHA1(input_url, strlen(input_url), hashed_160bits); for(i=0; i < sizeof(hashed_160bits); i++) { sprintf(hashed_hex + i*2, "%02x", hashed_160bits[i]); } // 确保字符串以'\0'结尾(虽然sprintf已经处理,但显式写更安全) hashed_hex[40] = '\0'; strcpy(hashed_url, hashed_hex); return hashed_url; } int main() { char *input_url; char *hashed_url; while(1) { input_url = malloc(sizeof(char)* 1024); hashed_url = malloc(sizeof(char) * 1024); // 可选:初始化内存避免垃圾数据 memset(input_url, 0, 1024); memset(hashed_url, 0, 1024); printf("input url> "); scanf("%s", input_url); if (strcmp(input_url, "bye") == 0) { free(hashed_url); free(input_url); break; } sha1_hash(input_url, hashed_url); printf("hashed_url: %s\n", hashed_url); free(hashed_url); free(input_url); } return 0; }
额外说明
- 我还在代码里加了
hashed_hex[40] = '\0';,虽然sprintf循环结束后刚好会在第40位(索引从0开始)自动写入终止符,但显式添加能避免任何边界情况的字符串截断问题。 - 初始化内存的步骤可以防止你后续如果不小心使用了未赋值的内存区域时出现奇怪问题,是个好习惯。
内容的提问来源于stack exchange,提问作者Yeon
相关产品推荐
相关产品推荐

