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())