62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
def mod_inv(a, m):
|
|
# Calcul de l'inverse modulaire de a modulo m avec l'algorithme d'Euclide étendu
|
|
def egcd(a, b):
|
|
if b == 0:
|
|
return a, 1, 0
|
|
else:
|
|
g, x, y = egcd(b, a % b)
|
|
return g, y, x - (a // b) * y
|
|
g, x, _ = egcd(a, m)
|
|
if g != 1:
|
|
raise Exception('Pas d\'inverse modulaire')
|
|
else:
|
|
return x % m
|
|
|
|
def matrix_det_2x2(matrix):
|
|
# Déterminant 2x2
|
|
return matrix[0][0]*matrix[1][1] - matrix[0][1]*matrix[1][0]
|
|
|
|
def matrix_mod_inv_2x2(matrix, modulus):
|
|
det = matrix_det_2x2(matrix) % modulus
|
|
det_inv = mod_inv(det, modulus)
|
|
|
|
# Matrice adjointe (cofacteurs transposés)
|
|
inv_matrix = [
|
|
[matrix[1][1] * det_inv % modulus, (-matrix[0][1]) * det_inv % modulus],
|
|
[(-matrix[1][0]) * det_inv % modulus, matrix[0][0] * det_inv % modulus]
|
|
]
|
|
return inv_matrix
|
|
|
|
def text_to_numbers(text):
|
|
return [ord(c) - ord('a') for c in text.lower()]
|
|
|
|
def numbers_to_text(numbers):
|
|
return ''.join(chr(n + ord('a')) for n in numbers)
|
|
|
|
def hill_decrypt(ciphertext, key):
|
|
modulus = 26
|
|
key_numbers = text_to_numbers(key)
|
|
key_matrix = [key_numbers[:2], key_numbers[2:]]
|
|
inv_key_matrix = matrix_mod_inv_2x2(key_matrix, modulus)
|
|
|
|
ciphertext_numbers = text_to_numbers(ciphertext)
|
|
plaintext_numbers = []
|
|
|
|
for i in range(0, len(ciphertext_numbers), 2):
|
|
pair = ciphertext_numbers[i:i+2]
|
|
# Multiplication matrice-vecteur modulaire
|
|
decrypted_pair = [
|
|
(inv_key_matrix[0][0] * pair[0] + inv_key_matrix[0][1] * pair[1]) % modulus,
|
|
(inv_key_matrix[1][0] * pair[0] + inv_key_matrix[1][1] * pair[1]) % modulus
|
|
]
|
|
plaintext_numbers.extend(decrypted_pair)
|
|
|
|
return numbers_to_text(plaintext_numbers)
|
|
|
|
# Variables données
|
|
clef = "IJDK"
|
|
mot_de_passe_chiffre = "yzhxvq"
|
|
|
|
# Déchiffrement
|
|
message_dechiffre = hill_decrypt(mot_de_passe_chiffre, clef)
|
|
print("Message déchiffré :", message_dechiffre)
|