Mercurial > hgrepos > Python > apps > py-cutils
view shasum.py @ 5:bbcb225640de
Handle standard and BSD-style output formats
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 04 Dec 2020 13:14:47 +0100 |
| parents | 67d10529ce88 |
| children | a21e83c855cc |
line wrap: on
line source
r""" :Author: Franz Glasner :Copyright: (c) 2020 Franz Glasner. All rights reserved. :License: BSD 3-Clause "New" or "Revised" License. See :ref:`LICENSE <license>` for details. If you cannot find LICENSE see <https://opensource.org/licenses/BSD-3-Clause> :ID: @(#) HGid$ """ from __future__ import print_function import argparse import hashlib import sys PY2 = sys.version_info[0] < 3 CHUNK_SIZE = 1024 * 1024 * 1024 def main(argv=None): aparser = argparse.ArgumentParser( description="Python implementation of shasum", fromfile_prefix_chars='@') aparser.add_argument( "--binary", "-b", action="store_false", dest="text_mode", default=False, help="read in binary mode (default)") aparser.add_argument( "--bsd", "-B", action="store_true", help="write BSD style output") aparser.add_argument( "--text", "-t", action="store_true", dest="text_mode", default=False, help="read in text mode (not yet supported)") aparser.add_argument( "files", nargs="*", metavar="FILE") opts = aparser.parse_args(args=argv) if opts.text_mode: print("ERROR: text mode not supported", file=sys.stderr) sys.exit(78) # :manpage:`sysexits(3)` EX_CONFIG if opts.bsd: out = out_bsd else: out = out_std if not opts.files: opts.files.append('-') if len(opts.files) == 1 and opts.files[0] == '-': if PY2: if sys.platform == "win32": import os. msvcrt msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) source = sys.stdin else: source = sys.stdin.buffer out(sys.stdout, compute_digest(hashlib.sha256, source), None, "SHA256", True) else: for fn in opts.files: with open(fn, "rb") as source: out(sys.stdout, compute_digest(hashlib.sha256, source), fn, "SHA256", True) def out_bsd(dest, digest, filename, digestname, binary): if filename is None: print(digest, file=dest) else: print("{} ({}) = {}".format(digestname, filename, digest), file=dest) def out_std(dest, digest, filename, digestname, binary): print("{} {}{}".format(digest, '*' if binary else ' ', '-' if filename is None else filename), file=dest) def compute_digest(hashobj, instream): """ :param hashobj: a :mod:`hashlib` compatible hash algorithm type or factory :param instream: a bytes input stream to read the data to be hashed from :return: the digest in hex form :rtype: str """ h = hashobj() while True: buf = instream.read(CHUNK_SIZE) if buf is not None: if len(buf) == 0: break h.update(buf) return h.hexdigest() if __name__ == "__main__": sys.exit(main())
