checksum.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. from hashlib import new as newhash
  2. from os import stat
  3. from os.path import isfile
  4. import sys
  5. def verifyFile(filePath, fileLength, checksums):
  6. actualLength = stat(filePath).st_size
  7. if actualLength != fileLength:
  8. raise OSError(
  9. 'Expected length %d, actual length %d' % (fileLength, actualLength)
  10. )
  11. hashers = {}
  12. for algo in checksums.keys():
  13. try:
  14. hashers[algo] = newhash(algo)
  15. except ValueError as ex:
  16. raise OSError('Failed to create "%s" hasher: %s' % (algo, ex))
  17. bufSize = 16384
  18. with open(filePath, 'rb') as inp:
  19. while True:
  20. buf = inp.read(bufSize)
  21. if not buf:
  22. break
  23. for hasher in hashers.values():
  24. hasher.update(buf)
  25. for algo, hasher in sorted(hashers.items()):
  26. if checksums[algo] != hasher.hexdigest():
  27. raise OSError('%s checksum mismatch' % algo)
  28. def main(filePath, fileLengthStr, checksumStrs):
  29. if not isfile(filePath):
  30. print('No such file: %s' % filePath, file=sys.stderr)
  31. sys.exit(2)
  32. try:
  33. fileLength = int(fileLengthStr)
  34. except ValueError:
  35. print('Length should be an integer', file=sys.stderr)
  36. sys.exit(2)
  37. checksums = {}
  38. for checksumStr in checksumStrs:
  39. try:
  40. algo, hashval = checksumStr.split('=')
  41. except ValueError:
  42. print('Invalid checksum format: %s' % checksumStr, file=sys.stderr)
  43. sys.exit(2)
  44. else:
  45. checksums[algo] = hashval
  46. print('Validating: %s' % filePath)
  47. try:
  48. verifyFile(filePath, fileLength, checksums)
  49. except OSError as ex:
  50. print('Validation FAILED: %s' % ex, file=sys.stderr)
  51. sys.exit(1)
  52. else:
  53. print('Validation passed')
  54. sys.exit(0)
  55. if __name__ == '__main__':
  56. if len(sys.argv) >= 3:
  57. main(
  58. sys.argv[1],
  59. sys.argv[2],
  60. sys.argv[3 : ]
  61. )
  62. else:
  63. print(
  64. 'Usage: python3 checksum.py FILE LENGTH (ALGO=HASH)*',
  65. file=sys.stderr
  66. )
  67. sys.exit(2)