2016-12-29 21:32:28 +01:00
|
|
|
import hashlib
|
|
|
|
|
2016-12-29 21:23:54 +01:00
|
|
|
def feed_file(h, f):
|
|
|
|
"""Feed data read from an open file into the hashlib instance."""
|
|
|
|
|
|
|
|
while True:
|
|
|
|
data = f.read(65536)
|
|
|
|
if len(data) == 0:
|
|
|
|
# end of file
|
|
|
|
break
|
|
|
|
h.update(data)
|
|
|
|
|
|
|
|
def feed_file_path(h, path):
|
|
|
|
"""Feed data read from a file (to be opened by this function) into the hashlib instance."""
|
|
|
|
|
|
|
|
with open(path, 'rb') as f:
|
|
|
|
feed_file(h, f)
|
|
|
|
|
2016-12-29 21:29:07 +01:00
|
|
|
def file_digest(algorithm, path):
|
|
|
|
"""Calculate the digest of a file and return it in hexadecimal notation."""
|
2016-12-29 21:32:28 +01:00
|
|
|
|
2016-12-29 21:29:07 +01:00
|
|
|
h = algorithm()
|
2016-12-29 21:23:54 +01:00
|
|
|
feed_file_path(h, path)
|
|
|
|
return h.hexdigest()
|
2016-12-29 21:29:07 +01:00
|
|
|
|
2016-12-29 21:43:47 +01:00
|
|
|
def guess_digest_algorithm(digest):
|
|
|
|
l = len(digest)
|
|
|
|
if l == 32:
|
|
|
|
return hashlib.md5
|
2016-12-29 21:19:40 +01:00
|
|
|
elif l == 40:
|
|
|
|
return hashlib.sha1
|
|
|
|
elif l == 64:
|
|
|
|
return hashlib.sha256
|
2016-12-29 21:43:47 +01:00
|
|
|
else:
|
|
|
|
return None
|
2016-12-29 21:40:54 +01:00
|
|
|
|
|
|
|
def verify_file_digest(path, expected_digest):
|
|
|
|
"""Verify the digest of a file, and return True if the digest matches with the given expected digest."""
|
|
|
|
|
2016-12-29 21:43:47 +01:00
|
|
|
algorithm = guess_digest_algorithm(expected_digest)
|
|
|
|
assert(algorithm is not None)
|
|
|
|
return file_digest(algorithm, path) == expected_digest
|