import numpy as np def letter_to_num(letter): return ord(letter.upper()) - ord('A') def num_to_letter(num): return chr(num + ord('A')) def matrix_mod_inv(key): det = int(round(np.linalg.det(key))) det_mod = det % 26 det_inv = pow(det_mod, -1, 26) adj = np.array([[key[1, 1], -key[0, 1]], [-key[1, 0], key[0, 0]]]) return (det_inv * adj) % 26 def cipher(text: str, key: int): text_upper = text.upper().replace(' ', '') if not validate_key(key): print("Macierz klucz nie jest odwracalna, wybierz innÄ…") exit(1) if len(text_upper) % 2 != 0: text_upper += "X" nums = [letter_to_num(letter) for letter in text_upper] mat = np.array(nums).reshape(-1, 2).T c = (key @ mat) % 26 return "".join(num_to_letter(n) for n in c.T.flatten()) def decipher(text: str, key: int): text_upper = text.upper().replace(' ', '') if not validate_key(key): print("Macierz klucz nie jest odwracalna, wybierz innÄ…") exit(1) key_inv = matrix_mod_inv(key) if len(text_upper) % 2 != 0: text_upper += "X" nums = [letter_to_num(letter) for letter in text_upper] mat = np.array(nums).reshape(-1, 2).T p = (key_inv @ mat) % 26 return "".join(num_to_letter(n) for n in p.T.flatten()) def validate_key(key) -> bool: key = np.asarray(key) if key.shape != (2, 2): return False if not np.all((0 <= key) & (key < 26)): return False det = int(round(np.linalg.det(key))) det_mod = det % 26 return np.gcd(det_mod, 26) == 1 if __name__ == "__main__": key = np.array([[3, 3], [2, 5]]) test_text = "TEST" ciphered_text = cipher(test_text, key) deciphered_text = decipher(ciphered_text, key) print("Text:", test_text) print("Cipher:", ciphered_text) print("Decipher:", deciphered_text)