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

Python hashlib返回结果不一致,请求排查代码问题

问题排查:哈希值每次计算不一致的原因及修复方案

我编写的代码每次运行时,hasher.hexdigest()返回的结果都不一致,但files列表中的文件从未发生修改。需求是仅当当前配置文件中的校验和与这三个文件通过hashlib计算出的哈希值不匹配时,才生成新的配置文件。请帮忙排查代码问题:

def should_generate_new_settings(qt_settings_generated_path: Path) -> tuple[bool, str]:
    """ compare checksum of user_settings.json and the current ini file to what is stored in the currently generated settings file """
    generate = False
    hasher = hashlib.new('md5')
    if not qt_settings_generated_path.exists():
        generate = True

    try:
        # if the file is corrupt, it may have a filesize of 0.
        generated_file = qt_settings_generated_path.stat()
        if generated_file.st_size < 1:
            generate = True

        files = [paths.user_settings_path, paths.settings_generated_path, Path(__file__)]
        for path in files:
            file_contents = path.read_bytes()
            hasher.update(file_contents)

        with qt_settings_generated_path.open('r') as file:
            lines = file.read().splitlines()

        checksum_prefix = '# checksum: '
        for line in lines:
            if line.startswith(checksum_prefix):
                file_checksum = line.lstrip(checksum_prefix)
                if file_checksum != hasher.hexdigest():
                    generate = True
                    break
    except FileNotFoundError:
        generate = True

    return (generate, hasher.hexdigest())

问题原因及修复

核心问题

你将生成后的配置文件本身(paths.settings_generated_path)加入了哈希计算的文件列表,而这个文件每次生成时会写入新的校验和,内容必然变化,导致每次计算的哈希值不一致。此外,代码逻辑冗余,哈希对象初始化和更新时机不合理,可能导致异常场景下哈希计算不完整。

修复方案

  1. 移除生成文件的校验:仅将原始配置文件(paths.user_settings_path)和脚本文件(Path(__file__))纳入哈希计算,这两个文件才是决定是否需要重新生成配置的依据。
  2. 优化逻辑顺序:先判断生成文件的存在性和完整性,符合条件时直接返回生成结果,避免后续不必要的操作。
  3. 独立初始化哈希对象:每次计算哈希都重新创建hasher,确保计算过程独立,无累计更新问题。

修正后的代码

def should_generate_new_settings(qt_settings_generated_path: Path) -> tuple[bool, str]:
    """比较user_settings.json、当前脚本文件的校验和与已生成配置文件中存储的校验和,判断是否需要生成新配置"""
    # 先判断是否需要直接生成新配置
    if not qt_settings_generated_path.exists() or qt_settings_generated_path.stat().st_size < 1:
        hasher = hashlib.new('md5')
        # 仅校验原始配置和脚本文件
        files = [paths.user_settings_path, Path(__file__)]
        for path in files:
            file_contents = path.read_bytes()
            hasher.update(file_contents)
        return (True, hasher.hexdigest())

    try:
        # 计算当前基准文件的哈希值
        hasher = hashlib.new('md5')
        files = [paths.user_settings_path, Path(__file__)]
        for path in files:
            file_contents = path.read_bytes()
            hasher.update(file_contents)
        current_checksum = hasher.hexdigest()

        # 读取并对比已生成文件中的校验和
        with qt_settings_generated_path.open('r') as file:
            checksum_prefix = '# checksum: '
            for line in file:
                line = line.strip()
                if line.startswith(checksum_prefix):
                    stored_checksum = line.lstrip(checksum_prefix).strip()
                    if stored_checksum != current_checksum:
                        return (True, current_checksum)
                    break
        # 校验和匹配或未找到校验行,无需生成
        return (False, current_checksum)
    except FileNotFoundError:
        # 兜底异常处理,重新计算哈希并返回需要生成
        hasher = hashlib.new('md5')
        files = [paths.user_settings_path, Path(__file__)]
        for path in files:
            file_contents = path.read_bytes()
            hasher.update(file_contents)
        return (True, hasher.hexdigest())

内容的提问来源于stack exchange,提问作者Ryan Glenn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:45:15