forked from Imagelibrary/littlefs
The naive implementation is simpler, less code, and more likely to be correct, each of these are more valuable than speed in our debug scripts. We're in Python anyways (no offense Python!). Plus I think it's good to show that the underlying logic of CRCs aren't really that complex, at least until we throw optimizations into the mix.
81 lines
2.1 KiB
Python
Executable File
81 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import io
|
|
import os
|
|
import struct
|
|
import sys
|
|
|
|
|
|
def openio(path, mode='r', buffering=-1):
|
|
# allow '-' for stdin/stdout
|
|
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):
|
|
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'):
|
|
print('%08x' % crc32c(bytes(int(path, 16) for path in paths)))
|
|
|
|
# interpret as strings
|
|
elif args.get('string'):
|
|
for path in paths:
|
|
print('%08x' % crc32c(path.encode('utf8')))
|
|
|
|
# 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}))
|