Skip to content

Instantly share code, notes, and snippets.

@sitnin
Created April 7, 2012 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sitnin/2332477 to your computer and use it in GitHub Desktop.
Save sitnin/2332477 to your computer and use it in GitHub Desktop.
Hash a string and print it to stdout
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = "Gregory Sitnin <sitnin@gmail.com>"
__copyright__ = "Gregory Sitnin, 2012"
__version__ = "1.0"
import sys
import argparse
import hashlib
try:
import bcrypt
except ImportError:
pass
try:
import scrypt
from random import randint
from base64 import b64encode, b64decode
def randstr(length):
return ''.join(chr(randint(0, 255)) for i in range(length))
def scrypt_hash_password(password, maxtime=0.5, datalength=64):
return scrypt.encrypt(randstr(datalength), password, maxtime=maxtime)
def scrypt_verify_password(hashed_password, guessed_password, maxtime=0.5):
try:
scrypt.decrypt(hashed_password, guessed_password, maxtime)
return True
except scrypt.error:
return False
except ImportError:
pass
def parse_args():
args_parser = argparse.ArgumentParser(version=__version__,
description="Hash a string and print it to stdout",
epilog="NOTE: This program is capable of hashing with bcrypt and scrypt if the corresponding python modules installed (py-bcrypt, scrypt). Other hashing routines using standard hashlib module."
)
subparsers = args_parser.add_subparsers(dest="method", help="hashing method")
string_parser = argparse.ArgumentParser(add_help=False)
string_parser.add_argument('string', help='string to hash')
string_parser.add_argument('-v', '--verbose', action="store_true", help='verbose output')
subparsers.add_parser('md5', parents=[string_parser])
subparsers.add_parser('sha1', parents=[string_parser])
subparsers.add_parser('sha256', parents=[string_parser])
subparsers.add_parser('sha384', parents=[string_parser])
subparsers.add_parser('sha512', parents=[string_parser])
try:
bcrypt
bcrypt_parser = subparsers.add_parser('bcrypt', parents=[string_parser])
bcrypt_parser.add_argument('-r', '--rounds', type=int, default=10, help='hashing rounds')
except NameError:
pass
try:
scrypt
scrypt_parser = subparsers.add_parser('scrypt', parents=[string_parser])
scrypt_parser.add_argument('-l', '--length', type=int, default=64, help='data length')
scrypt_parser.add_argument('-t', '--time', type=float, default=0.05, help='minimum timespan to decrypt')
except NameError:
pass
return args_parser.parse_args()
if __name__ == "__main__":
args = parse_args()
strhash = ""
verified = False
if args.method == "md5":
strhash = hashlib.md5(args.string).hexdigest()
verified = True
elif args.method == "sha1":
strhash = hashlib.sha1(args.string).hexdigest()
verified = True
elif args.method == "sha256":
strhash = hashlib.sha256(args.string).hexdigest()
verified = True
elif args.method == "sha384":
strhash = hashlib.sha384(args.string).hexdigest()
verified = True
elif args.method == "sha512":
strhash = hashlib.sha512(args.string).hexdigest()
verified = True
elif args.method == "scrypt":
strhash = b64encode(scrypt.encrypt(randstr(args.length), args.string, args.time))
verified = scrypt_verify_password(b64decode(strhash), args.string, args.time * 1.5) # WORKAROUND: sometimes, library exceeds decryption time limit and fails verification. so decrypt timespan extended
elif args.method == "bcrypt":
strhash = bcrypt.hashpw(args.string, bcrypt.gensalt(args.rounds))
verified = strhash == bcrypt.hashpw(args.string, strhash)
if args.verbose:
print("stringhash v%s (c) %s" % (__version__, __copyright__))
if len(strhash) > 0 and args.verbose:
print("HASHED: %s\nLENGTH: %d\nSTATUS: %s" % (strhash, len(strhash), "Verified" if verified else "Not verified"))
if args.method == "scrypt":
print("WARNING: Output of the hashing function is base64-wrapped")
elif len(strhash) > 0:
print(strhash)
else:
print("error while hashing")
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment