import numpy as np

def lettre_vers_nombre(lettre):
    return ord(lettre.upper()) - ord('A')

def nombre_vers_lettre(nombre):
    return chr((nombre % 26) + ord('A'))

def matrice_inverse_modulo(matrice, modulo):
    det = int(np.round(np.linalg.det(matrice)))
    det_inv = pow(det, -1, modulo)
    matrice_inv = det_inv * np.round(det * np.linalg.inv(matrice)).astype(int) % modulo
    return matrice_inv

def chiffrer(message, cle):
    message = message.upper().replace(" ", "")
    if len(message)%2 != 0:
        message += message[-1]
    n = len(cle)
    chiffre = ""

    for i in range(0, len(message), 2):
        vecteur = np.array([lettre_vers_nombre(message[i]), lettre_vers_nombre(message[i+1])])
        vecteur_chiffre = cle.dot(vecteur) % 26
        chiffre += nombre_vers_lettre(vecteur_chiffre[0]) + nombre_vers_lettre(vecteur_chiffre[1])

    return chiffre

def dechiffrer(message_chiffre, cle):
    cle_inv = matrice_inverse_modulo(cle, 26)
    message = ""

    for i in range(0, len(message_chiffre), 2):
        vecteur = np.array([lettre_vers_nombre(message_chiffre[i]), lettre_vers_nombre(message_chiffre[i+1])])
        vecteur_dechiffre = cle_inv.dot(vecteur) % 26
        message += nombre_vers_lettre(vecteur_dechiffre[0]) + nombre_vers_lettre(vecteur_dechiffre[1])

    return message

# Exemple d'utilisation
cle = np.array([[3, 3], [2, 5]])
message = "MATH"

message_chiffre = chiffrer(message, cle)
print(f"Message chiffré : {message_chiffre}")

message_dechiffre = dechiffrer(message_chiffre, cle)
print(f"Message déchiffré : {message_dechiffre}")
