The script below will unroll 1048576 (20-bits) x 32-bytes (32-megabytes) of SHA256 hash digests into memory and will perform 1048576 (20-bits) of array index look ups to get the final hash digest.
import hashlib def tohex(h): o = "" for c in h: d = ord(c) f = "" if (d < 16): f = "0" d = hex(d) o += (f + d[2:]) return o def scrypt(p, r, m): h = hashlib.sha256(p).digest() #print(tohex(h)) k = h l = [] s = 0 while (s < m): k = hashlib.sha256(k).digest() #print(s,tohex(k)) l.append(k) s += 1 k = h i = 0 n = (m - 1) while (i < r): tt = ((ord(k[28]) << 24) | (ord(k[29]) << 16) | (ord(k[30]) << 8) | (ord(k[31]) << 0)) j = (tt & n) #print(i,hex(tt),j,tohex(l[j])) k = l[j] i += 1 return tohex(k) s = scrypt("P@ssW0rd1!", 2**20, 2**20) print(s)
cat /proc/cpuinfo | grep -i 'model.*name' | head -n 1 ; date ; python scrypt.py ; date model name : Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz Sat Jan 25 13:20:42 EST 2014 3f26b65f9c3ae151c7113efd3abe57a5e7257ba9b9010ec53acde03112b5a9b1 Sat Jan 25 13:20:44 EST 2014
# cat /proc/cpuinfo | grep -i 'model.*name' | head -n 1 ; date ; python scrypt.py ; date model name : Intel(R) Xeon(R) CPU E5-2650 0 @ 2.00GHz Sun Jan 26 19:18:13 UTC 2014 3f26b65f9c3ae151c7113efd3abe57a5e7257ba9b9010ec53acde03112b5a9b1 Sun Jan 26 19:18:16 UTC 2014
sysctl -n machdep.cpu.brand_string ; date ; python scrypt.py ; date Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz Sat 25 Jan 2014 13:16:15 EST 3f26b65f9c3ae151c7113efd3abe57a5e7257ba9b9010ec53acde03112b5a9b1 Sat 25 Jan 2014 13:16:19 EST
and also, a random py script to generate random passwords:
import os import random import string import sys f = open(sys.argv[1], "r") for l in f.readlines(): l = l.strip() p = [] for x in range(0, int(sys.argv[2])): if ((x % 4) == 0): p.append(random.choice(string.digits)) elif ((x % 4) == 1): p.append(random.choice(string.uppercase)) elif ((x % 4) == 2): p.append(random.choice(string.lowercase)) elif ((x % 4) == 3): p.append(random.choice("~!@#$%^&*+")) random.shuffle(p) s = "".join(p) print(l + "," + s) f.close()