Advertisement
JoshuaB

hash.py

Jun 16th, 2013
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.48 KB | None | 0 0
  1. import os
  2. import sys
  3. import hashlib
  4. import argparse
  5.  
  6. BUFFER_SIZE = 4 * 1024
  7.  
  8.  
  9. class HashResult(object):
  10.     def __init__(self, path, hasher):
  11.         """Creates new HashResult
  12.  
  13.        :param path: the path of the file
  14.        :type path: str
  15.  
  16.        :param hasher: the resulting hash object
  17.        """
  18.         self.path = path
  19.         self.hasher = hasher
  20.  
  21.  
  22. def main():
  23.     args = get_args()
  24.  
  25.     for path in args.paths:
  26.         hash_generator = calculate_hash(args.hash_method, path, args.recursive)
  27.  
  28.         column_len = 0
  29.         i = 0
  30.         for result in hash_generator:
  31.             file_name = os.path.basename(result.path)
  32.             cur_column_len = len(file_name)
  33.             if cur_column_len > column_len:
  34.                 column_len = cur_column_len
  35.             formatting = "{0:" + str(column_len) + "} {1}"
  36.  
  37.             print formatting.format(file_name, result.hasher.hexdigest())
  38.             i += 1
  39.  
  40.         print "\n%i files were hashed." % i
  41.  
  42.  
  43. def calculate_hash(method, path, is_recursive):
  44.     """A generator that calculates the hash of the path using the hashing method.
  45.  
  46.    :param method: the hashing method to use
  47.    :type method: str
  48.  
  49.    :param path: the path to hash
  50.    :type path: str
  51.  
  52.    :param is_recursive: if recursive hashing is enabled
  53.    :type is_recursive: bool
  54.  
  55.    :return: the generator that yields a :ref
  56.    """
  57.     try:
  58.         # Try to append the working directory if the path is relative
  59.         if not os.path.isfile(path) or os.path.isdir(path):
  60.             path = os.path.join(os.getcwd(), path)
  61.  
  62.         # Check if the path is actually a folder
  63.         if os.path.isdir(path):
  64.             if not is_recursive:
  65.                 print "Info: Recursive scanning is disabled. Skipping directory '%s'.\n" \
  66.                       "      Specify option '-r' to enable recursive scanning." % path
  67.                 return
  68.             else:
  69.                 for p in os.listdir(path):
  70.                     generator = calculate_hash(method, os.path.join(path, p), is_recursive)
  71.                     for result in generator:
  72.                         yield result
  73.                 return
  74.  
  75.         hasher = get_hasher(method)
  76.         size = os.path.getsize(path)
  77.         f = open(path, 'r')
  78.  
  79.         i = 0
  80.         while i < size:
  81.             data = f.read(BUFFER_SIZE)
  82.             hasher.update(data)
  83.             i += BUFFER_SIZE
  84.  
  85.         yield HashResult(path, hasher)
  86.     except (IOError, OSError):
  87.         print "Error: Unable to read '%s'." % path
  88.  
  89.  
  90. def get_hasher(hash_method):
  91.     try:
  92.         return hashlib.new(hash_method)
  93.     except ValueError:
  94.         print "Error: Unsupported hash method '%s'." % hash_method
  95.         sys.exit(-1)
  96.  
  97.  
  98. def get_args():
  99.     # hash_method = sys.argv[1]
  100.     # files = sys.argv[2:]
  101.  
  102.     parser = argparse.ArgumentParser()
  103.     parser.add_argument('hash_method', metavar='method',
  104.                         help="the hashing method to use. Can be a value of: " +
  105.                              str(hashlib.algorithms)[1:-1].replace("'", ""))
  106.     parser.add_argument('paths', metavar='path', nargs='+',
  107.                         help="path to run the hash on")
  108.     parser.add_argument('-r', '--recursive', dest='recursive',
  109.                         help="enables all sub-files and sub-directories to be hashed when a "
  110.                              "directory is specified",
  111.                         action="store_true")
  112.     return parser.parse_args()
  113.  
  114. if __name__ == '__main__':
  115.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement