Last active
August 29, 2015 13:56
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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