Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.02 KB | None | 0 0
  1. import numpy as np
  2. import gmpy2
  3.  
  4.  
  5. def _minor(matrix: np.array, i, j):
  6. return matrix[
  7. np.array(list(range(i))+list(range(i+1, matrix.shape[0])))[:, np.newaxis],
  8. np.array(list(range(j))+list(range(j+1, matrix.shape[1])))
  9. ]
  10.  
  11.  
  12. def _adjoint(matrix: np.array):
  13. minors = np.zeros_like(matrix)
  14. for i in range(matrix.shape[0]):
  15. for j in range(matrix.shape[1]):
  16. minors[i][j] = round(np.linalg.det(_minor(matrix, i, j))) * (-1) ** (i + j)
  17.  
  18. return minors.T
  19.  
  20.  
  21. def _matrix_modulo_invert(matrix: np.array, modulo):
  22. inverse_det = int(gmpy2.invert(int(round(np.linalg.det(matrix))), modulo))
  23. return inverse_det * _adjoint(matrix) % modulo
  24.  
  25.  
  26. class Hill:
  27. def __init__(self, key: str):
  28. if len(key) != 4:
  29. raise ValueError("Wrong key length")
  30.  
  31. key = key.upper()
  32. self.encrypt_key = np.array([ord(x) - ord("A") for x in key])
  33. self.encrypt_key = self.encrypt_key.reshape((2, 2))
  34. self.decrypt_key = _matrix_modulo_invert(self.encrypt_key, 26)
  35.  
  36. def _encrypt_with_key(self, message: str, key: np.array) -> str:
  37. message = message.upper()
  38. ciphertext = []
  39. for i in range(0, len(message), key.shape[0]):
  40. block = message[i:i + key.shape[0]]
  41. block_vector = np.vstack(
  42. np.array([ord(x) - ord("A") for x in block])
  43. )
  44.  
  45. ciphertext_block_vector = np.matmul(
  46. key, block_vector
  47. ) % 26
  48.  
  49. ciphertext_block = [
  50. chr(x + ord("A")) for x in ciphertext_block_vector
  51. ]
  52. ciphertext.extend(ciphertext_block)
  53.  
  54. return "".join(ciphertext)
  55.  
  56. def encrypt(self, message: str) -> str:
  57. return self._encrypt_with_key(message, self.encrypt_key)
  58.  
  59. def decrypt(self, message: str) -> str:
  60. return self._encrypt_with_key(message, self.decrypt_key)
  61.  
  62.  
  63. def main():
  64. hill = Hill("GHJL")
  65. encrypt = hill.encrypt("ZOHF")
  66. print(encrypt)
  67. print(hill.decrypt(encrypt))
  68.  
  69.  
  70. if __name__ == "__main__":
  71. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement