56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import binascii
|
|
import struct
|
|
import argparse
|
|
|
|
def calculate_mpeg2_crc32(data):
|
|
"""
|
|
Calculate MPEG-2 style CRC32 (Polynomial: 0x04C11DB7, Initial: 0xFFFFFFFF)
|
|
Note: Result is NOT inverted (unlike standard CRC32)
|
|
"""
|
|
crc = 0xFFFFFFFF
|
|
for byte in data:
|
|
crc ^= byte << 24
|
|
for _ in range(8):
|
|
if crc & 0x80000000:
|
|
crc = (crc << 1) ^ 0x04C11DB7
|
|
else:
|
|
crc = crc << 1
|
|
crc &= 0xFFFFFFFF
|
|
return crc
|
|
|
|
def process_file(filename):
|
|
try:
|
|
with open(filename, 'rb+') as f:
|
|
# Verify exact 256 bytes size
|
|
f.seek(0, 2)
|
|
if f.tell() != 256:
|
|
raise ValueError(f"File must be exactly 256 bytes (got {f.tell()} bytes)")
|
|
|
|
f.seek(0)
|
|
data = f.read(252)
|
|
if len(data) != 252:
|
|
raise ValueError("Couldn't read 252 bytes from file")
|
|
|
|
crc = calculate_mpeg2_crc32(data)
|
|
f.seek(252)
|
|
f.write(struct.pack('<I', crc))
|
|
|
|
print(f"Success: Updated {filename} with CRC32 0x{crc:08X} at offset 252")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"Error processing {filename}: {str(e)}")
|
|
return False
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description='Calculate MPEG-2 CRC32 for first 252 bytes and write to last 4 bytes of 256-byte file')
|
|
parser.add_argument('filename', help='Binary file to process (must be 256 bytes)')
|
|
args = parser.parse_args()
|
|
|
|
if not process_file(args.filename):
|
|
exit(1)
|