Mercurial > hgrepos > Python > apps > py-cutils
comparison shasum.py @ 2:5510a39a2d04
Basic hashing with proper binary stdin/stdout support for Py2, Py3 and Windows
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 04 Dec 2020 11:41:25 +0100 |
| parents | bbf4e0f5b651 |
| children | 5a6ed622846c |
comparison
equal
deleted
inserted
replaced
| 1:bbf4e0f5b651 | 2:5510a39a2d04 |
|---|---|
| 8 <https://opensource.org/licenses/BSD-3-Clause> | 8 <https://opensource.org/licenses/BSD-3-Clause> |
| 9 :ID: @(#) HGid$ | 9 :ID: @(#) HGid$ |
| 10 | 10 |
| 11 """ | 11 """ |
| 12 | 12 |
| 13 from __future__ import print_function | |
| 13 | 14 |
| 14 import argparse | 15 import argparse |
| 15 import hashlib | 16 import hashlib |
| 16 import sys | 17 import sys |
| 17 | 18 |
| 18 | 19 |
| 20 PY2 = sys.version_info[0] < 3 | |
| 21 | |
| 22 CHUNK_SIZE = 1024 * 1024 * 1024 | |
| 23 | |
| 24 | |
| 19 def main(argv=None): | 25 def main(argv=None): |
| 26 if argv is None: | |
| 27 argv = sys.argv[1:] | |
| 20 | 28 |
| 21 aparser = argparse.ArgumentParser( | 29 aparser = argparse.ArgumentParser( |
| 22 description="Python implementation of shasum", | 30 description="Python implementation of shasum", |
| 23 fromfile_prefix_chars='@') | 31 fromfile_prefix_chars='@') |
| 32 aparser.add_argument( | |
| 33 "files", nargs="*", metavar="FILE") | |
| 24 | 34 |
| 25 opts = aparser.parse_args(args=argv) | 35 opts = aparser.parse_args(args=argv) |
| 36 | |
| 37 if not opts.files: | |
| 38 opts.files.append("-") | |
| 39 for fn in opts.files: | |
| 40 if fn == "-": | |
| 41 if PY2: | |
| 42 if sys.platform == "win32": | |
| 43 import os. msvcrt | |
| 44 msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) | |
| 45 source = sys.stdin | |
| 46 else: | |
| 47 source = sys.stdin.buffer | |
| 48 print(compute_digest(hashlib.sha256, source)) | |
| 49 else: | |
| 50 with open(fn, "rb") as source: | |
| 51 print(compute_digest(hashlib.sha256, source)) | |
| 26 | 52 |
| 27 | 53 |
| 28 def compute_digest(hashobj, instream): | 54 def compute_digest(hashobj, instream): |
| 29 """ | 55 """ |
| 30 | 56 |
| 31 :param hashobj: a :mod:`hashlib` compatible hash algorithm instance | 57 :param hashobj: a :mod:`hashlib` compatible hash algorithm type or factory |
| 32 :param instream: a bytes input stream to read the data to be hashed from | 58 :param instream: a bytes input stream to read the data to be hashed from |
| 33 :return: the digest in hex form | 59 :return: the digest in hex form |
| 34 :rtype: str | 60 :rtype: str |
| 35 | 61 |
| 36 """ | 62 """ |
| 37 | 63 h = hashobj() |
| 64 while True: | |
| 65 buf = instream.read(CHUNK_SIZE) | |
| 66 if buf is not None: | |
| 67 if len(buf) == 0: | |
| 68 break | |
| 69 h.update(buf) | |
| 70 return h.hexdigest() | |
| 71 | |
| 72 | |
| 38 if __name__ == "__main__": | 73 if __name__ == "__main__": |
| 39 sys.exit(main()) | 74 sys.exit(main()) |
