Exercise: cracking a password

The following requires you first install kocham, which can be found as a zipfile in the tutorial repository. Python 2.7 is required. If the install fails, try installing setuptools first.


In [ ]:
$ unzip kocham.zip
$ cd kocham
$ python setup.py install

In [1]:
"""
a toy password cracker
"""
import time
import itertools
from multiprocess.dummy import Pool
import kocham.imap as imap
import kocham.corpus as corpus
stopwords = corpus.stopwords
ipassword = corpus.ipassword
compare = imap.login

# turn on verbosity
corpus.VERBOSE = True

# set the password to "solve"
imap.setpass('catdog@123')

# set a delay, to simulate connection time to a server
imap.setdelay(0.0)

# select a list of possible words and a possible set of characters
words = ['cat','dog','horse','apple','foo','bar','python','phobia']
chars = '1234567890!@#$'

# configure the minimum and maximum password length
args = (words, chars, 8, 10)
# configure the minimum and maximum word length, and the maximum number of words
kwds = dict(minword=3, maxword=8, size=2)

In [2]:
# build the password generator
passwd = ipassword(flatten=True, *args, **kwds)

start = time.time()

# solve
for p in passwd:
    x = compare(p)
    if x:
        print x
        break

end = time.time() - start
print "finished in: %s" % end


horsehorse: {base:10, char:(0,0), subs: 0, sep: 0}
horsebar: {base:8, char:(0,2), subs: 0, sep: 0}
horseapple: {base:10, char:(0,0), subs: 0, sep: 0}
horsedog: {base:8, char:(0,2), subs: 0, sep: 0}
horsecat: {base:8, char:(0,2), subs: 0, sep: 0}
horsefoo: {base:8, char:(0,2), subs: 0, sep: 0}
phobiabar: {base:9, char:(0,1), subs: 0, sep: 0}
phobiadog: {base:9, char:(0,1), subs: 0, sep: 0}
phobiacat: {base:9, char:(0,1), subs: 0, sep: 0}
phobiafoo: {base:9, char:(0,1), subs: 0, sep: 0}
barbar: {base:6, char:(2,4), subs: 0, sep: 0}
barapple: {base:8, char:(0,2), subs: 0, sep: 0}
barpython: {base:9, char:(0,1), subs: 0, sep: 0}
bardog: {base:6, char:(2,4), subs: 0, sep: 0}
barcat: {base:6, char:(2,4), subs: 0, sep: 0}
barfoo: {base:6, char:(2,4), subs: 0, sep: 0}
appleapple: {base:10, char:(0,0), subs: 0, sep: 0}
appledog: {base:8, char:(0,2), subs: 0, sep: 0}
applecat: {base:8, char:(0,2), subs: 0, sep: 0}
applefoo: {base:8, char:(0,2), subs: 0, sep: 0}
pythondog: {base:9, char:(0,1), subs: 0, sep: 0}
pythoncat: {base:9, char:(0,1), subs: 0, sep: 0}
pythonfoo: {base:9, char:(0,1), subs: 0, sep: 0}
dogdog: {base:6, char:(2,4), subs: 0, sep: 0}
dogcat: {base:6, char:(2,4), subs: 0, sep: 0}
catdog@123
finished in: 32.731760025

In [3]:
# rebuild the password generator
passwd = ipassword(flatten=True, *args, **kwds)

start = time.time()

# solve
for x in itertools.imap(compare, passwd):
    if x:
        print x
        break

end = time.time() - start
print "finished in: %s" % end


horsehorse: {base:10, char:(0,0), subs: 0, sep: 0}
horsebar: {base:8, char:(0,2), subs: 0, sep: 0}
horseapple: {base:10, char:(0,0), subs: 0, sep: 0}
horsedog: {base:8, char:(0,2), subs: 0, sep: 0}
horsecat: {base:8, char:(0,2), subs: 0, sep: 0}
horsefoo: {base:8, char:(0,2), subs: 0, sep: 0}
phobiabar: {base:9, char:(0,1), subs: 0, sep: 0}
phobiadog: {base:9, char:(0,1), subs: 0, sep: 0}
phobiacat: {base:9, char:(0,1), subs: 0, sep: 0}
phobiafoo: {base:9, char:(0,1), subs: 0, sep: 0}
barbar: {base:6, char:(2,4), subs: 0, sep: 0}
barapple: {base:8, char:(0,2), subs: 0, sep: 0}
barpython: {base:9, char:(0,1), subs: 0, sep: 0}
bardog: {base:6, char:(2,4), subs: 0, sep: 0}
barcat: {base:6, char:(2,4), subs: 0, sep: 0}
barfoo: {base:6, char:(2,4), subs: 0, sep: 0}
appleapple: {base:10, char:(0,0), subs: 0, sep: 0}
appledog: {base:8, char:(0,2), subs: 0, sep: 0}
applecat: {base:8, char:(0,2), subs: 0, sep: 0}
applefoo: {base:8, char:(0,2), subs: 0, sep: 0}
pythondog: {base:9, char:(0,1), subs: 0, sep: 0}
pythoncat: {base:9, char:(0,1), subs: 0, sep: 0}
pythonfoo: {base:9, char:(0,1), subs: 0, sep: 0}
dogdog: {base:6, char:(2,4), subs: 0, sep: 0}
dogcat: {base:6, char:(2,4), subs: 0, sep: 0}
catdog@123
finished in: 32.8478620052

In [ ]:
# rebuild the password generator
passwd = ipassword(flatten=True, *args, **kwds)

start = time.time()

# solve
tp = Pool(50)
for x in tp.imap_unordered(compare, passwd):
    if x:
        print x
        break
tp.close()
tp.join()

end = time.time() - start
print "finished in: %s" % end

(this takes a long time...)


In [4]:
"""
some useful parallel iterated map constructs
"""
def icompare(pwds):
    import itertools
    res = itertools.imap(compare, pwds)
    for x in res:
        if x:
            return x
    return

def uicompare(pwds, n=50):
    from multiprocess.dummy import Pool
    tp = Pool(n)
    res = tp.imap_unordered(compare, pwds)
    for x in res:
        if x:
            return x
    return

In [5]:
# rebuild the password generator, this time don't flatten to a single interator
passwd = ipassword(flatten=False, *args, **kwds)

start = time.time()

# solve
for p in passwd:
    for i in p:
        x = compare(i)
        if x:
            print x
            break
    if x:
        break


end = time.time() - start
print "finished in: %s" % end


horsehorse: {base:10, char:(0,0), subs: 0, sep: 0}
horsebar: {base:8, char:(0,2), subs: 0, sep: 0}
horseapple: {base:10, char:(0,0), subs: 0, sep: 0}
horsedog: {base:8, char:(0,2), subs: 0, sep: 0}
horsecat: {base:8, char:(0,2), subs: 0, sep: 0}
horsefoo: {base:8, char:(0,2), subs: 0, sep: 0}
phobiabar: {base:9, char:(0,1), subs: 0, sep: 0}
phobiadog: {base:9, char:(0,1), subs: 0, sep: 0}
phobiacat: {base:9, char:(0,1), subs: 0, sep: 0}
phobiafoo: {base:9, char:(0,1), subs: 0, sep: 0}
barbar: {base:6, char:(2,4), subs: 0, sep: 0}
barapple: {base:8, char:(0,2), subs: 0, sep: 0}
barpython: {base:9, char:(0,1), subs: 0, sep: 0}
bardog: {base:6, char:(2,4), subs: 0, sep: 0}
barcat: {base:6, char:(2,4), subs: 0, sep: 0}
barfoo: {base:6, char:(2,4), subs: 0, sep: 0}
appleapple: {base:10, char:(0,0), subs: 0, sep: 0}
appledog: {base:8, char:(0,2), subs: 0, sep: 0}
applecat: {base:8, char:(0,2), subs: 0, sep: 0}
applefoo: {base:8, char:(0,2), subs: 0, sep: 0}
pythondog: {base:9, char:(0,1), subs: 0, sep: 0}
pythoncat: {base:9, char:(0,1), subs: 0, sep: 0}
pythonfoo: {base:9, char:(0,1), subs: 0, sep: 0}
dogdog: {base:6, char:(2,4), subs: 0, sep: 0}
dogcat: {base:6, char:(2,4), subs: 0, sep: 0}
catdog@123
finished in: 32.6554210186

Can you find a looping pattern that significantly speeds up the time-to-solution?

How different are your results when the cracker has a small delay time like: imap.setdelay(0.0001)?


In [ ]: