74 lines
2.4 KiB
Python
74 lines
2.4 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
import sys
|
|||
|
|
import struct
|
|||
|
|
|
|||
|
|
def calculate_checksum(data):
|
|||
|
|
"""计算小端序校验和:每4字节相加后取反(32位无符号)"""
|
|||
|
|
if len(data) % 4 != 0:
|
|||
|
|
raise ValueError("Data length must be multiple of 4")
|
|||
|
|
|
|||
|
|
sum_val = 0
|
|||
|
|
# 遍历所有4字节块(最后4字节除外)
|
|||
|
|
for i in range(0, len(data)-4, 4):
|
|||
|
|
chunk = data[i:i+4]
|
|||
|
|
value = struct.unpack('<I', chunk)[0] # 小端序解析
|
|||
|
|
sum_val = (sum_val + value) & 0xFFFFFFFF # 32位溢出保护
|
|||
|
|
|
|||
|
|
return (~sum_val) & 0xFFFFFFFF # 取反并保持32位
|
|||
|
|
|
|||
|
|
def process_file(filename):
|
|||
|
|
"""处理文件的主函数"""
|
|||
|
|
try:
|
|||
|
|
# 读取文件内容(二进制模式)
|
|||
|
|
with open(filename, 'rb+') as f:
|
|||
|
|
original_data = f.read()
|
|||
|
|
data_len = len(original_data)
|
|||
|
|
|
|||
|
|
# ========== 验证阶段 ==========
|
|||
|
|
# 1. 检查文件长度是否为4的倍数
|
|||
|
|
if data_len % 4 != 0:
|
|||
|
|
raise ValueError(f"文件长度 {data_len} 不是4的倍数")
|
|||
|
|
|
|||
|
|
# 2. 检查第二个4字节是否等于文件长度
|
|||
|
|
if data_len >= 8:
|
|||
|
|
declared_length = struct.unpack('<I', original_data[4:8])[0]
|
|||
|
|
if declared_length != data_len:
|
|||
|
|
raise ValueError(
|
|||
|
|
f"长度声明不匹配:文件头声明={declared_length},实际={data_len}"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# ========== 计算校验和 ==========
|
|||
|
|
checksum = calculate_checksum(original_data)
|
|||
|
|
|
|||
|
|
# ========== 写入校验和 ==========
|
|||
|
|
# 定位到文件最后4字节
|
|||
|
|
f.seek(-4, os.SEEK_END)
|
|||
|
|
f.write(struct.pack('<I', checksum)) # 小端序写入
|
|||
|
|
|
|||
|
|
print(f"[成功] 文件 {filename} 已更新校验码:0x{checksum:08X}")
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"[错误] 处理文件 {filename} 失败:{str(e)}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
# 参数检查
|
|||
|
|
if len(sys.argv) != 2:
|
|||
|
|
print("用法: python checksum.py <文件名>")
|
|||
|
|
sys.exit(1)
|
|||
|
|
|
|||
|
|
input_file = sys.argv[1]
|
|||
|
|
|
|||
|
|
# 文件存在性检查
|
|||
|
|
if not os.path.isfile(input_file):
|
|||
|
|
print(f"[错误] 文件不存在: {input_file}")
|
|||
|
|
sys.exit(1)
|
|||
|
|
|
|||
|
|
# 执行处理
|
|||
|
|
if not process_file(input_file):
|
|||
|
|
sys.exit(1)
|