3. CRC-32计算

任务目标

实现标准CRC-32(IEEE 802.3,多项式0x04C11DB7)算法,计算任意文件的校验值,并与系统标准工具(cksum或python3 zlib.crc32)结果比对,验证实现正确性。

实现方案

采用查表法提升效率,核心包含:表生成、逐字节更新、文件流式计算三个部分。算法参数:多项式0x04C11DB7,初始值0xFFFFFFFF,输入输出均不反转,最终结果异或0xFFFFFFFF。

完整代码(crc32.py)

import sys
import zlib

# 生成CRC-32查找表(多项式0x04C11DB7,MSB优先)
CRC_TABLE = []
for i in range(256):
    crc = i << 24
    for _ in range(8):
        if crc & 0x80000000:
            crc = ((crc << 1) ^ 0x04C11DB7) & 0xFFFFFFFF
        else:
            crc = (crc << 1) & 0xFFFFFFFF
    CRC_TABLE.append(crc)

def crc32_file(filepath, chunk_size=65536):
    """计算文件的CRC-32校验值(标准IEEE 802.3)"""
    crc = 0xFFFFFFFF
    with open(filepath, 'rb') as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            for byte in chunk:
                idx = ((crc >> 24) ^ byte) & 0xFF
                crc = ((crc << 8) & 0xFFFFFFFF) ^ CRC_TABLE[idx]
    return crc ^ 0xFFFFFFFF

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print("用法: python3 crc32.py <文件路径>")
        sys.exit(1)
    filepath = sys.argv[1]
    my_crc = crc32_file(filepath)
    # 用zlib标准实现交叉验证
    with open(filepath, 'rb') as f:
        std_crc = zlib.crc32(f.read()) & 0xFFFFFFFF
    print(f"本实现CRC-32: {my_crc:08X}")
    print(f"标准CRC-32:   {std_crc:08X}")
    print("结果一致" if my_crc == std_crc else "结果不一致!")

运行与验证

  1. 保存上述代码为 crc32.py
  2. 准备测试文件(如 test.bin),可用 echo "hello" > test.txt 创建
  3. 运行:python3 crc32.py test.txt
  4. 预期输出(以内容 hello\n 为例):
本实现CRC-32: 3610A686
标准CRC-32:   3610A686
结果一致

判定通过条件:程序输出“结果一致”,且本实现与标准库计算值完全相同。可额外用 cksum test.txt 命令核对(注意cksum输出为十进制,转换为十六进制后应一致)。

关键说明

  • 算法采用MSB优先、多项式0x04C11DB7、初值0xFFFFFFFF、结果异或0xFFFFFFFF,与zlib及cksum完全兼容
  • 分块读取(64KB)保证大文件内存安全,流式计算无需加载整个文件
  • 若需验证其他文件,直接替换路径参数即可,无需修改代码