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()