You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:42:55