checksum.py 1.7 KB

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