from cipher import Cipher class Playfair(Cipher): def encrypt(self, text, key = '', decrypt = False): """Retorna text cifrado com a cifra de Playfair. key - chave a ser usada; havendo chave, o alfabeto sera iniciado com ela decrypt - se True, decifra; se False, cifra """ ciphertext = '' text = text.upper() text = text.replace('J', 'I').replace(' ', '') # checa se o texto contem par de letras iguais text = self.check_double(text) # se text nao tiver numero par de letras if len(text) % 2: text += 'W' # cria a tabela self.square = self.create_square(key) for i in range(0, len(text), 2): ciphertext += self.change_pair(text[i:i + 2], decrypt) return ciphertext.upper() def decrypt(self, ciphertext, key = ''): """Retorna o ciphertext decifrado com a cifra de Playfair""" return self.encrypt(ciphertext.upper(), key, True).lower() def check_double(self, text): out = '' for idx in range(0, len(text), 2): pair = text[idx:idx+2] if len(pair) > 1 and pair[0] == pair[1]: out += pair[0] + 'W' + pair[1] else: out += pair return out def change_pair(self, pair, decrypt = False): """Retorna as posicoes de um par de letras de uma matriz 5x5.""" # retorno - valor a ser retornado quando se atinge o limite da tabela # limite - valor de limite das celulas da tabela # passo - valor de incremento/decremento if decrypt: retorno = 4 limite = -1 passo = -1 else: retorno = 0 limite = 5 passo = 1 coord1, coord2 = self.coords(pair) if coord1[0] == coord2[0]: # caso em que as duas letras estao na mesma linha coord1[1] += passo coord2[1] += passo elif coord1[1] == coord2[1]: # caso em que as duas letras estao na mesma coluna coord1[0] += passo coord2[0] += passo else: # caso em que as duas letras nao estao na mesma linha nem mesma coluna coord1[1], coord2[1] = coord2[1], coord1[1] coord1 = [retorno if x == limite else x for x in coord1] coord2 = [retorno if x == limite else x for x in coord2] return self.letter(coord1) + self.letter(coord2) def coords(self, pair): """Retorna as coordenadas de um par de letras numa matriz.""" coords = [] for letter in pair: for line in range(len(self.square)): if letter in self.square[line]: coords.append([line, self.square[line].index(letter)]) break return coords def letter(self, coord): """Retorna a letra com a coordenada dada""" return self.square[coord[0]][coord[1]]