forked from Imagelibrary/littlefs
This matches the behavior of paths and helps figure out which string is associated with which crc32c/parity when checksumming multiple strings: $ ./scripts/crc32c.py -s hi hello f59dd9c2 hi 9a71bb4c hello It also might help clear up confusion if someone forgets to quote a string with spaces inside it.
96 lines
2.5 KiB
Python
Executable File
96 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# prevent local imports
|
|
if __name__ == "__main__":
|
|
__import__('sys').path.pop(0)
|
|
|
|
import io
|
|
import os
|
|
import struct
|
|
import sys
|
|
|
|
try:
|
|
import crc32c as crc32c_lib
|
|
except ModuleNotFoundError:
|
|
crc32c_lib = None
|
|
|
|
|
|
# open with '-' for stdin/stdout
|
|
def openio(path, mode='r', buffering=-1):
|
|
import os
|
|
if path == '-':
|
|
if 'r' in mode:
|
|
return os.fdopen(os.dup(sys.stdin.fileno()), mode, buffering)
|
|
else:
|
|
return os.fdopen(os.dup(sys.stdout.fileno()), mode, buffering)
|
|
else:
|
|
return open(path, mode, buffering)
|
|
|
|
def crc32c(data, crc=0):
|
|
if crc32c_lib is not None:
|
|
return crc32c_lib.crc32c(data, crc)
|
|
else:
|
|
crc ^= 0xffffffff
|
|
for b in data:
|
|
crc ^= b
|
|
for j in range(8):
|
|
crc = (crc >> 1) ^ ((crc & 1) * 0x82f63b78)
|
|
return 0xffffffff ^ crc
|
|
|
|
|
|
def main(paths, **args):
|
|
# interpret as sequence of hex bytes
|
|
if args.get('hex'):
|
|
bytes_ = [b for path in paths for b in path.split()]
|
|
print('%08x' % crc32c(bytes(int(b, 16) for b in bytes_)))
|
|
|
|
# interpret as strings
|
|
elif args.get('string'):
|
|
for path in paths:
|
|
print('%08x %s' % (crc32c(path.encode('utf8')), path))
|
|
|
|
# default to interpreting as paths
|
|
else:
|
|
if not paths:
|
|
paths = [None]
|
|
|
|
for path in paths:
|
|
with openio(path or '-', 'rb') as f:
|
|
# calculate crc
|
|
crc = 0
|
|
while True:
|
|
block = f.read(io.DEFAULT_BUFFER_SIZE)
|
|
if not block:
|
|
break
|
|
|
|
crc = crc32c(block, crc)
|
|
|
|
# print what we found
|
|
if path is not None:
|
|
print('%08x %s' % (crc, path))
|
|
else:
|
|
print('%08x' % crc)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import argparse
|
|
import sys
|
|
parser = argparse.ArgumentParser(
|
|
description="Calculates crc32cs.",
|
|
allow_abbrev=False)
|
|
parser.add_argument(
|
|
'paths',
|
|
nargs='*',
|
|
help="Paths to read. Reads stdin by default.")
|
|
parser.add_argument(
|
|
'-x', '--hex',
|
|
action='store_true',
|
|
help="Interpret as a sequence of hex bytes.")
|
|
parser.add_argument(
|
|
'-s', '--string',
|
|
action='store_true',
|
|
help="Interpret as strings.")
|
|
sys.exit(main(**{k: v
|
|
for k, v in vars(parser.parse_intermixed_args()).items()
|
|
if v is not None}))
|