C语言提取小端值时避免文件指针偏移影响哈希计算
解决文件指针偏移导致哈希计算错误的问题
你的问题核心是:读取第12个字节后,额外调用fgetc(fp)读取高字节,导致该字节被跳过、未参与后续哈希计算,破坏了哈希链的连续性。下面提供两种可行的修复方案:
方案一:用ungetc将额外读取的字节放回文件流
这种方法最简单直接,读取高字节后将其放回文件流,让下一次循环的fgetc能正常读取并参与哈希计算:
void check_drop(char *drop_pathname) { FILE *fp; fp = fopen(drop_pathname, "rb"); int count = 0, pathname_length = 0, c; uint8_t drop_hash = 0, current_hash = 0; while ((c = fgetc(fp)) != EOF) { drop_hash = droplet_hash(current_hash, c); printf("\ndroplet_hash(0x%02x, 0x%02x) = 0x%02x", current_hash, c, drop_hash); current_hash = drop_hash; if (count == 12) { unsigned int small_hex_val = 0; int next_c = fgetc(fp); if (next_c == EOF) { // 处理文件意外结束的异常情况 break; } small_hex_val |= (c & 0xFF); // 第12个字节作为小端值的低字节 small_hex_val |= ((next_c & 0xFF) << 8); // 读取的下一个字节作为高字节 pathname_length = (int)small_hex_val; ungetc(next_c, fp); // 将高字节放回文件流,保证下一次循环能读取到它 } count++; } fclose(fp); }
原理说明
ungetc(next_c, fp)会把读取到的高字节重新推回文件输入流头部,下一次调用fgetc(fp)时会优先读取该字节,确保原本被跳过的字节能正常参与哈希计算,维持字节读取顺序和哈希链的完整性。
方案二:通过标志位延迟处理高字节
如果不想使用ungetc(比如部分流不支持回退操作),可以设置标志位,延迟到下一次循环读取高字节并计算pathname_length:
void check_drop(char *drop_pathname) { FILE *fp; fp = fopen(drop_pathname, "rb"); int count = 0, pathname_length = 0, c; uint8_t drop_hash = 0, current_hash = 0; int need_high_byte = 0; unsigned char low_byte = 0; while ((c = fgetc(fp)) != EOF) { // 优先处理延迟的高字节计算 if (need_high_byte) { unsigned int small_hex_val = 0; small_hex_val |= low_byte; small_hex_val |= ((c & 0xFF) << 8); pathname_length = (int)small_hex_val; need_high_byte = 0; } drop_hash = droplet_hash(current_hash, c); printf("\ndroplet_hash(0x%02x, 0x%02x) = 0x%02x", current_hash, c, drop_hash); current_hash = drop_hash; if (count == 12) { low_byte = c; // 保存当前字节作为小端值的低字节 need_high_byte = 1; // 标记下一次循环需要读取高字节 } count++; } fclose(fp); }
原理说明
当count==12时,仅保存当前字节为低字节并设置标志位,下一次循环读取到的字节会先用来计算pathname_length,再正常参与哈希计算,完全避免了额外的文件指针偏移问题。
修复后,原本被跳过的0x00字节会被正常传入droplet_hash(0xbf, 0x00),后续哈希计算将与正确输出完全对齐。
内容的提问来源于stack exchange,提问作者Kenny
相关产品推荐
相关产品推荐

