Skip to content

Instantly share code, notes, and snippets.

@winny-
Last active August 29, 2015 13:56
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save winny-/8876315 to your computer and use it in GitHub Desktop.
Simple python tool for creating and checking digests. Useful on old Macs that don't have shasum(1), but have python with hashlib.
#!/usr/bin/env python
# Makes me mad that I had to write this. Damn you mac os x 10.5.8.
# I, Winston Weinert, hereby put this file in the public domain.
import hashlib
class Checksum(object):
ALGORITHM_MAP = {'md5': hashlib.md5,
'sha1': hashlib.sha1,
'sha224': hashlib.sha224,
'sha256': hashlib.sha256,
'sha384': hashlib.sha384,
'sha512': hashlib.sha512}
CSV = "csv"
SIMPLE = "simple"
FORMATS = (CSV, SIMPLE)
def __init__(self, file_name, algorithm=None, buffer_size=(1024*1024*200)):
if algorithm is None:
algorithm = 'sha256'
if algorithm not in self.ALGORITHM_MAP:
raise ValueError('Invalid algorithm "{0}"'.format(algorithm))
self.file_name = file_name
self.algorithm = algorithm
self.buffer_size = buffer_size
self.file = open(file_name)
self.hash = self.ALGORITHM_MAP[algorithm]()
self.data_buffer = self.file.read(self.buffer_size)
while self.data_buffer != '':
self.hash.update(self.data_buffer)
self.data_buffer = self.file.read(self.buffer_size)
self.hexdigest = self.hash.hexdigest()
self.file.close()
def format_digest(self, format_choice=None):
if format_choice is None:
format_choice = self.SIMPLE
if format_choice not in self.FORMATS:
raise ValueError('Invalid format_choice "{0}"'
.format(format_choice))
if format_choice == self.SIMPLE:
output = "{0} {1}".format(self.hexdigest, self.file_name)
elif format_choice == self.CSV:
output = "{0},{1},{2}".format(self.file_name,
self.algorithm, self.hexdigest)
return output
if __name__ == "__main__":
import optparse
def join_list(my_list):
length = len(my_list)
if length == 0:
return ''
elif length == 1:
return my_list[0]
elif length == 2:
return ' or '.join(my_list)
else:
head = ', '.join(my_list[:-1])
return head + ', or ' + my_list[-1]
parser = optparse.OptionParser()
parser.add_option("-a", "--algorithm", dest="algorithm",
help="ALGORITHM_MAP: {0}"
.format(join_list(list(Checksum.ALGORITHM_MAP.keys()))),
default='sha256')
parser.add_option("-f", "--format", dest="format",
help="formats: {0}".format(join_list(Checksum.FORMATS)),
default=Checksum.SIMPLE)
parser.add_option("-c", "--check", action="store_true", dest="check")
(options, args) = parser.parse_args()
algorithm = options.algorithm
format_type = options.format
if len(args) < 1:
parser.error('Must specify at least one file.')
if not options.check:
for item in args:
print(Checksum(item, algorithm).format_digest(format_type))
else:
for item in args:
with open(item) as f:
for line in f.readlines():
line = line.rstrip('\n').split(',')
filename, algorithm_, digest = line[0], line[1], line[2]
c = Checksum(filename, algorithm_)
if c.hexdigest == digest:
print("{0}: PASSED".format(filename))
else:
print("{0}: FAILED".format(filename))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment