def fourSquare(text,keys,decode=False,mode="IJ",printkey=False): # Convert the squares to numpy arrays to we can use numpy's indexing sq1 = np.array(makeSquare(keys[0],mode=mode)) sq2 = np.array(makeSquare(keys[1],mode=mode)) alphasq = np.array(makeSquare("",mode=mode)) if mode == "IJ" or mode == "JI": text = text.replace("J","I") if mode == "KQ" or mode == "QK": text = text.replace("Q","K") if mode == "CK" or mode == "KC": text = text.replace("C","K") if printkey == True: n = 5 if mode == "EX": n = 6 for i in range(n): print(" ".join(alphasq[i]),end=" ") print(" ".join(sq1[i])) print() for i in range(n): print(" ".join(sq2[i]),end=" ") print(" ".join(alphasq[i])) return "" if len(text) % 2 == 1: text += "X" G = groups(text,2) if decode == False: out = "" for g in G: A = np.where(sq1 == g[0]) B = np.where(sq2 == g[1]) out += alphasq[A[0],B[1]][0] out += alphasq[B[0],A[1]][0] return out if decode == True: out = "" for g in G: A = np.where(alphasq == g[0]) B = np.where(alphasq == g[1]) out += sq1[A[0],B[1]][0] out += sq2[B[0],A[1]][0] return out
def ADFGX(text,keys=["A",[0,1]],decode=False,printkey=False): """ :param text: The text to be encrypyed. Must be alphanumeric and uppercase. The letter J will be replaced with I. :param keys: Two keywords, the first to prepare a 5x5 square a the second to control a columnar transport cipher. :param decode: Boolean. If false encrypt plaintext. If true decode ciphertext """ # Adjust the text if necessary text = text.replace("J","I") while len(text) % len(keys[1]) != 0: text += "X" alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ" alpha = alphabetPermutation(keys[0],alpha) if printkey == True: sq = makeSquare(keys[0],mode="EX") for i in range(6): print(" ".join(sq[i])) pairs = product("ADFGX",repeat=2) D1 = {} D2 = {} for letter,pair in zip(alpha,pairs): D1[letter] = "".join(pair) D2["".join(pair)] = letter # The ADFGX cipher has a roughly symmetric encode and decoding process # the only difference is that the columnar transport is reversed. # Turn every letter into a pair of symbols ctext = "".join([D1[i] for i in text]) # Scramble the symbols, this will break apart some of the pairs ctext = columnarTransport(ctext,keys[1],decode=decode) # Now take the scrambled symbols and turn them back into letters ctext = groups(ctext,2) ctext = "".join([D2[i] for i in ctext]) return ctext
def ADFGVX(text, keys=["A", [0, 1]], decode=False, printkey=False): """ :param text: The text to be encrypyed. Must be alphanumeric and uppercase. :param keys: Two keywords, the first to prepare a 6x6 square a the second to control a columnar transport cipher. :param decode: Boolean. If false encrypt plaintext. If true decode ciphertext """ while len(text) % len(keys[1]) != 0: text += "X" alpha = alphabetPermutation(keys[0], "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") sq = makeSquare(keys[0], mode="EX") if printkey == True: for i in range(6): print(" ".join(sq[i])) pairs = product("ADFGVX", repeat=2) D1 = {} D2 = {} for letter, pair in zip(alpha, pairs): D1[letter] = "".join(pair) D2["".join(pair)] = letter # Turn every letter into a pair of symbols ctext = "".join([D1[i] for i in text]) # Scramble the symbols, this will break apart some of the pairs ctext = columnarTransport(ctext, keys[1], decode=decode) # Now take the scrambled symbols and turn them back into letters ctext = groups(ctext, 2) ctext = "".join([D2[i] for i in ctext]) return ctext
def twoSquare(text, keys, decode=False, mode="EX", printkey=False): # Convert the squares to numpy arrays to we can use numpy's indexing sq1 = np.array(makeSquare(keys[0], mode)) sq2 = np.array(makeSquare(keys[1], mode)) if mode == "IJ" or mode == "JI": text = text.replace("J", "I") if mode == "KQ" or mode == "QK": text = text.replace("Q", "K") if mode == "CK" or mode == "KC": text = text.replace("C", "K") if len(text) % 2 == 1: text += "X" # Print out the key in a nice way if the user needs it if printkey == True: if mode == "EX": for i in range(6): print(" ".join(sq1[i])) print() for i in range(6): print(" ".join(sq2[i])) else: for i in range(5): print(" ".join(sq1[i])) print() for i in range(5): print(" ".join(sq2[i])) if mode == "EX": sz = 6 else: sz = 5 G = groups(text, 2) if decode == False: out = "" for g in G: A = np.where(sq1 == g[0]) B = np.where(sq2 == g[1]) if A[0] == B[0]: out += sq1[(A[0] + 1) % sz, A[1]][0] out += sq2[(B[0] + 1) % sz, B[1]][0] elif A[1] == B[1]: out += sq1[A[0], (A[1] + 1) % sz][0] out += sq2[B[0], (B[1] + 1) % sz][0] else: out += sq1[A[0], B[1]][0] out += sq2[B[0], A[1]][0] if decode == True: out = "" for g in G: A = np.where(sq1 == g[0]) B = np.where(sq2 == g[1]) if A[0] == B[0]: out += sq1[(A[0] - 1) % sz, A[1]][0] out += sq2[(B[0] - 1) % sz, B[1]][0] elif A[1] == B[1]: out += sq1[A[0], (A[1] - 1) % sz][0] out += sq2[B[0], (B[1] - 1) % sz][0] else: out += sq1[A[0], B[1]][0] out += sq2[B[0], A[1]][0] return out
def playfair(text, key, decode=False, mode="IJ", printkey=False): # Make sure the text will work correctly for a playfair cipher in this mode text = playfairPrep(text, mode=mode) # Derive the alphabet to be used for the key based on the mode sq = makeSquare(key, mode=mode) sqWhere = squareIndex(sq) if printkey == True: if mode == "EX": for i in range(6): print(" ".join(sq[i])) else: for i in range(5): print(" ".join(sq[i])) G = groups(text, 2) if decode == False: if mode == "EX": sz = 6 else: sz = 5 out = "" for g in G: A = sqWhere[g[0]] B = sqWhere[g[1]] # If they share a column if A[0] == B[0]: out += sq[A[0]][(A[1] + 1) % sz] out += sq[B[0]][(B[1] + 1) % sz] # If they share a row elif A[1] == B[1]: out += sq[(A[0] + 1) % sz][A[1]] out += sq[(B[0] + 1) % sz][B[1]] # Otherwise else: out += sq[A[0]][B[1]] out += sq[B[0]][A[1]] return out if decode == True: if mode == "EX": sz = 6 else: sz = 5 out = "" for g in G: A = sqWhere[g[0]] B = sqWhere[g[1]] if A[0] == B[0]: out += sq[A[0]][(A[1] - 1) % sz] out += sq[B[0]][(B[1] - 1) % sz] elif A[1] == B[1]: out += sq[(A[0] - 1) % sz][A[1]] out += sq[(B[0] - 1) % sz][B[1]] else: out += sq[A[0]][B[1]] out += sq[B[0]][A[1]] return out