class Polybius: def __init__(self): ## p_alphabet nao possui a letra j, que sera substituida ## pela letra i na cifragem e decifragem self.p_alphabet = 'abcdefghiklmnopqrstuvwxyz' self.p_alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789' def cipher_alphabet(self, password): ''' (str) -> str Retorna um alfabeto cifrado iniciado com o texto da palavra chave password ''' c_alphabet = [] p_alphabet = self.p_alphanum for ch in password: if ch not in c_alphabet: c_alphabet.append(ch) idx = p_alphabet.find(ch) p_alphabet = p_alphabet[idx:] + p_alphabet[:idx] for ch in p_alphabet: if ch not in c_alphabet: c_alphabet.append(ch) return ''.join(c_alphabet) def create_square(self, alphabet, lines): ''' (list, int) -> list of str Retorna uma tabela lista quadrada definida por lines com cada celula preenchida com um caracter de alphabet ''' square = [] temp = [] count = 0 for ch in alphabet: temp.append(ch) count += 1 if count == lines: square.append(temp) temp = [] count = 0 return square def select_square(self, key): ''' (int) -> list of str Retorna o quadrado de Polibio referente a key utilizada. Se key for True, usa-se o quadrado de Polibio com letras e numerais; Se key for uma string, retorna o quadrado de Polibio com key como palavra chave. Se nao houver key, usa-se o quadrado de Polibio padrao. ''' if key: if key == True: return self.create_square(self.p_alphanum, 6) else: return self.create_square(self.cipher_alphabet(str(key)), 6) return self.create_square(self.p_alphabet, 5) def encrypt(self, plaintext, key = None): ''' (str, str) -> str Retorna o plaintext cifrado com a cifra de Polibio. Se key = True, cifra com quadrado de Polibio com letras e numeros. Se key = uma string, cifra o quadrado de Polibio com key como palavra chave. Se nao houver key, cifra com o quadrado de polibio padrao. ''' square = self.select_square(key) ciphertext = '' for ch in plaintext.lower(): idx = 1 if ch == 'j': ch = 'i' for linha in square: if ch in linha: ciphertext += str(idx) + str(linha.index(ch) + 1) + ' ' idx += 1 return ciphertext def decrypt(self, ciphertext, key = None): ''' (str, str) -> str Retorna o ciphertext decifrado com a cifra de Polibio. Se key = True, decifra com quadrado de Polibio com letras e numeros. Se key = uma string, decifra o quadrado de Polibio com key como palavra chave. Se nao houver key, decifra com o quadrado de polibio padrao. ''' square = self.select_square(key) plaintext = '' ciphertext = str(ciphertext).replace(' ', '') for num in range(0, len(ciphertext), 2): var = int(ciphertext[num:num + 2]) i, j = var / 10, var % 10 if i - 1 < len(square) and j - i < len(square[0]): plaintext += square[i - 1][j - 1] return plaintext.lower()