\myheading{Forgotten password} You forgot a password, but this is what you remember: there was a name of your parent, or wife, or one of children. Also, someone's year of birth. And one punctuation character, which are so recommended in passwords. Can you enumerate all possible passwords? \lstinputlisting[style=custompy]{comb/password/pw1.py} \begin{lstlisting} jake1987! jake!1987 1987jake! 1987!jake !jake1987 ... 1963emily, 1963,emily ,emily1963 ,1963emily \end{lstlisting} ( 936 of them in total ) But nested for's are not aesthetically pleasing. They can be replaced with "cartesian product" operation: \lstinputlisting[style=custompy]{comb/password/pw2.py} And this is a way to memorize it: the length of the final result equals to lengths of all input lists multiplied with each other (like "product"). \lstinputlisting[style=custompy]{comb/password/pw21.py} \begin{lstlisting} ('jake', '1987', '!') ('jake', '1987', '@') ('jake', '1987', '#') ('jake', '1987', '$') ('jake', '1987', '%') ('jake', '1987', '&') ('jake', '1987', '*') ... ('emily', '1963', '*') ('emily', '1963', '-') ('emily', '1963', '=') ('emily', '1963', '_') ('emily', '1963', '+') ('emily', '1963', '.') ('emily', '1963', ',') \end{lstlisting} 4*3*13=156, and this is a size of a list, to be permuted... Now the new problem: some Latin characters may be uppercased, some are lowercased. I'll add another "cartesian product" operation to alter a final string in all possible ways: \lstinputlisting[style=custompy]{comb/password/pw3.py} \begin{lstlisting} JAke1987! JAkE1987! JAKe1987! JAKE1987! jake!1987 jakE!1987 jaKe!1987 jaKE!1987 ... ,1963eMIly ,1963eMIlY ,1963eMILy ,1963eMILY ,1963Emily ,1963EmilY ,1963EmiLy \end{lstlisting} ( 56160 passwords ) Now leetspeak\footnote{\href{https://www.urbandictionary.com/define.php?term=leet\%20speak}{urbandictionary.com}} This is somewhat popular only among youngsters, but still, this is what people of all age groups do: replacing "o" with "0" in their passwords, "e" with "3", etc. Let's add this as well: \lstinputlisting[style=custompy]{comb/password/pw4.py} \begin{lstlisting} jake1987! jakE1987! jak31987! jaKe1987! jaKE1987! jaK31987! ... ,1963EM1lY ,1963EM1Ly ,1963EM1LY ,19633mily ,19633milY ,19633miLy \end{lstlisting} ( 140400 passwords ) Obviously, you can't try all 140400 passwords on Facebook, Twitter or any other well-protected internet service. But this is a peace of cake to brute-force them all on password protected RAR-archive or feed them to John the Ripper, HashCat, Aircrack-ng, etc. All the files: \MakeURL{\RepoPath/comb/password}. \myhrule{} Now let's use combinations from itertools Python package. Let's say, you remember that your password has maybe your name, maybe name of your wife, your year of birth, or her, and maybe couple of symbols like \verb|!|, \verb|$|, \verb|^|. \begin{lstlisting} import itertools parts=["den", "xenia", "1979", "1985", "secret", "!", "$", "^"] for i in range(1, 6): # 1..5 for combination in itertools.combinations(parts, i): print "".join(combination) \end{lstlisting} Here we enumerate all combinations of given strings, 1-string combinations, then 2-, up to 5-string combinations. No string can appear twice. \begin{lstlisting} ... denxenia1979 denxenia1985 denxeniasecret denxenia! denxenia$ denxenia^ den19791985 den1979secret den1979! ... xenia1985secret$^ xenia1985!$^ xeniasecret!$^ 19791985secret!$ 19791985secret!^ ... \end{lstlisting} (218 passwords) Now let's permute all string in all possible ways: \begin{lstlisting} import itertools parts=["den", "xenia", "1979", "1985", "secret", "!", "$", "^"] for i in range(1, 6): # 1..5 for combination in itertools.combinations(parts, i): for permutation in itertools.permutations(list(combination)): print "".join(permutation) \end{lstlisting} \begin{lstlisting} ... ^den xenia1979 1979xenia xenia1985 1985xenia xeniasecret secretxenia xenia! !xenia ... ^!$1985secret ^!$secret1985 ^$1985secret! ^$1985!secret ^$secret1985! ^$secret!1985 ^$!1985secret ^$!secret1985 \end{lstlisting} (8800 passwords) And finally, let's alter all Latin characters in lower/uppercase ways and add leetspeek, as I did before: \begin{lstlisting} import itertools, string parts=["den", "xenia", "1979", "1985", "!", "$", "^"] for i in range(1, 6): # 1..5 for combination in itertools.combinations(parts, i): for permutation in itertools.permutations(list(combination)): s="".join(permutation) t=[] for char in s: if char.isalpha(): to_be_appended=[string.lower(char), string.upper(char)] if char.lower()=='e': to_be_appended.append('3') elif char.lower()=='i': to_be_appended.append('1') elif char.lower()=='o': to_be_appended.append('0') t.append(to_be_appended) else: t.append([char]) for q in itertools.product(*t): print "".join(q) \end{lstlisting} \begin{lstlisting} ... dEnxenia dEnxeniA dEnxenIa ... D3nx3N1a D3nx3N1A D3nXenia D3nXeniA D3nXenIa ... ^$1979!1985 ^$19851979! ^$1985!1979 ^$!19791985 ^$!19851979 \end{lstlisting} ( 1,348,657 passwords ) Again, you can't try to crack remote server with so many attempts, but this is really possible for password-protected archive, known hash, etc...