Skip to content

Instantly share code, notes, and snippets.

@Wh1terat
Last active June 18, 2024 21:25
Show Gist options
  • Save Wh1terat/f48594c6cc5b77b13d7dee0c503bffe7 to your computer and use it in GitHub Desktop.
Save Wh1terat/f48594c6cc5b77b13d7dee0c503bffe7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import argparse
__title__ = "Xanavi CRC Tool"
__version__ = "0.1"
__author__ = "Gareth Bryan"
__license__ = "MIT"
FILETYPES = {
#Type Start, End, 2sComp
"APP": (4, -4, True),
"DSP": (4, -4, True),
"CNFTBL": (12, -4, False),
# Many of the below seem to be pseudo-archives, TBD.
#"BTFW": (0, -4, True)
#"BOT": (,,) # BOT is a collection of files with multiple CRCs
#"VCAN_SUB": (,,)
#"DVD_MEC": (,,)
#"PROG": (,,)
#"DISP": (,,)
#"XMRADIO": (,,)
#"HDRADIO": (,,)
}
def main(args):
data = args.infile.read()
file_crc = data[-4:]
print(f"file crc : {file_crc.hex()}")
print("calculated : ", end="", flush=True)
calc_crc = crc(args.filetype, data)
print(calc_crc.hex())
if args.update:
if file_crc == calc_crc:
print("crc already matches")
else:
with open(f"{args.infile.name}.bak", "wb") as backup:
backup.write(data)
args.infile.seek(len(data)-4)
args.infile.write(calc_crc)
print("crc updated")
def crc(filetype, data):
start, end, twos = FILETYPES[filetype]
crc = 0
for chunk in (int.from_bytes(data[i:i+4], 'little') for i in range(start, len(data)-start+end, 4)):
crc = 0xffffffff & (crc + chunk) + (0xffffffff & (crc + chunk) < crc)
if twos:
crc = 2**32 - crc
return crc.to_bytes(4, 'little')
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="{} v{}".format(__title__, __version__)
)
parser.add_argument(
"-t",
help="File Type",
choices=FILETYPES.keys(),
dest="filetype"
)
parser.add_argument(
"-u",
help = "Update CRC",
action="store_true",
dest="update"
)
parser.add_argument(
"infile",
help="Input File",
type=argparse.FileType("r+b"),
)
args = parser.parse_args()
main(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment