On my slow laptop, crypt.crypt takes about 20 microseconds:
$ python -mtimeit -s'import crypt' 'crypt.crypt("foobar", "zappa")' 10000 loops, best of 3: 21.8 usec per loop
Thus, the brute force approach (truly the only reasonable one) is βpeculiarβ feasible. Using your conversion functions, you will get (ball score) about 100 converted words in dictionaries (mainly from capitalization changes), so about 40 million converted words from your dictionary. In 20 microseconds each, which takes about 800 seconds, call it 15 minutes to try to crack one of the passwords, which actually does not correspond to any of the options; the expected time is about half to crack the password that matches.
So, if you have 10 passwords for hacking, and all of them correspond to the converted dictionary word, you should do it in an hour or two. This is normal? Since you cannot do anything else but distribute this uncomfortable parallel problem across many nodes and cores, as you can understand (ah, and using, first of all, a faster machine) that may buy you, perhaps twice or so).
There is no deep optimization tricks that you can add, so the general logic will consist of a triple nested loop: one level goes in cycles on encrypted passwords, one above the words in the dictionary, one according to the variants of each dictionary word. There is not much difference in how you insert things (except that the cycle for options should be within the cycle for words, for simplicity). I recommend encapsulating "give me all variants of this word" as a generator (for simplicity, not speed) and otherwise minimize the number of function calls (for example, it makes no sense to use this function check_pass , because the built-in code is just as clear as it will be microscopically faster).
Alex martelli
source share