playfair.py


SUBMITTED BY: siriarah

DATE: Dec. 10, 2019, 3:02 p.m.

FORMAT: Python 3

SIZE: 3.1 kB

HITS: 671

  1. from cipher import Cipher
  2. class Playfair(Cipher):
  3. def encrypt(self, text, key = '', decrypt = False):
  4. """Retorna text cifrado com a cifra de Playfair.
  5. key - chave a ser usada; havendo chave, o alfabeto sera iniciado com ela
  6. decrypt - se True, decifra; se False, cifra
  7. """
  8. ciphertext = ''
  9. text = text.upper()
  10. text = text.replace('J', 'I').replace(' ', '')
  11. # checa se o texto contem par de letras iguais
  12. text = self.check_double(text)
  13. # se text nao tiver numero par de letras
  14. if len(text) % 2:
  15. text += 'W'
  16. # cria a tabela
  17. self.square = self.create_square(key)
  18. for i in range(0, len(text), 2):
  19. ciphertext += self.change_pair(text[i:i + 2], decrypt)
  20. return ciphertext.upper()
  21. def decrypt(self, ciphertext, key = ''):
  22. """Retorna o ciphertext decifrado com a cifra de Playfair"""
  23. return self.encrypt(ciphertext.upper(), key, True).lower()
  24. def check_double(self, text):
  25. out = ''
  26. for idx in range(0, len(text), 2):
  27. pair = text[idx:idx+2]
  28. if len(pair) > 1 and pair[0] == pair[1]:
  29. out += pair[0] + 'W' + pair[1]
  30. else:
  31. out += pair
  32. return out
  33. def change_pair(self, pair, decrypt = False):
  34. """Retorna as posicoes de um par de letras de uma matriz 5x5."""
  35. # retorno - valor a ser retornado quando se atinge o limite da tabela
  36. # limite - valor de limite das celulas da tabela
  37. # passo - valor de incremento/decremento
  38. if decrypt:
  39. retorno = 4
  40. limite = -1
  41. passo = -1
  42. else:
  43. retorno = 0
  44. limite = 5
  45. passo = 1
  46. coord1, coord2 = self.coords(pair)
  47. if coord1[0] == coord2[0]:
  48. # caso em que as duas letras estao na mesma linha
  49. coord1[1] += passo
  50. coord2[1] += passo
  51. elif coord1[1] == coord2[1]:
  52. # caso em que as duas letras estao na mesma coluna
  53. coord1[0] += passo
  54. coord2[0] += passo
  55. else:
  56. # caso em que as duas letras nao estao na mesma linha nem mesma coluna
  57. coord1[1], coord2[1] = coord2[1], coord1[1]
  58. coord1 = [retorno if x == limite else x for x in coord1]
  59. coord2 = [retorno if x == limite else x for x in coord2]
  60. return self.letter(coord1) + self.letter(coord2)
  61. def coords(self, pair):
  62. """Retorna as coordenadas de um par de letras numa matriz."""
  63. coords = []
  64. for letter in pair:
  65. for line in range(len(self.square)):
  66. if letter in self.square[line]:
  67. coords.append([line, self.square[line].index(letter)])
  68. break
  69. return coords
  70. def letter(self, coord):
  71. """Retorna a letra com a coordenada dada"""
  72. return self.square[coord[0]][coord[1]]

comments powered by Disqus