Adloun

Un chiffrement par substitution remplace chaque lettre par une autre…

Exercice d'entraînement · niveau 2 · NSI (première), chapitre 5 — Les dictionnaires · Applications

Énoncé

Un chiffrement par substitution remplace chaque lettre par une autre, selon une table. Écrire chiffrer et dechiffrer. Quelle propriété la table doit-elle avoir, et comment la vérifier ?

Corrigé


def est_bijective(table):
    """True si deux cles distinctes n'ont jamais la meme valeur."""
    return len(set(table.values())) == len(table)


def chiffrer(message, table):
    """Precondition : table bijective -- sinon le message serait
    indechiffrable."""
    assert est_bijective(table), "table non bijective : chiffrement irreversible"
    return "".join(table.get(c, c) for c in message)


def dechiffrer(message, table):
    return chiffrer(message, {v: k for k, v in table.items()})

Pourquoi la bijectivité, et pourquoi elle se teste ainsi. Si deux lettres se chiffrent pareil, le déchiffrement ne peut pas choisir : l'information est perdue pour de bon. len(set(table.values())) == len(table) le dit en une ligne — autant de valeurs distinctes que de clés. C'est exactement la condition qui rend inverse sans perte, revue sous un autre angle : le déchiffrement est l'inversion du dictionnaire.

Le table.get(c, c). Les caractères absents de la table — espaces, ponctuation — se recopient tels quels. La valeur par défaut est ici le caractère lui-même, ce qui évite un if dans la compréhension.

Vérification.


table = {"a": "z", "b": "y", "c": "x"}
assert chiffrer("abc", table) == "zyx"
assert dechiffrer(chiffrer("abc cab", table), table) == "abc cab"

try:
    chiffrer("ab", {"a": "z", "b": "z"})
    assert False
except AssertionError as e:
    assert "bijective" in str(e)

rot13 = {chr(97 + i): chr(97 + (i + 13) % 26) for i in range(26)}
assert chiffrer("bonjour", rot13) == "obawbhe"
assert chiffrer(chiffrer("bonjour", rot13), rot13) == "bonjour"

L'aller-retour dechiffrer(chiffrer(m)) == m est le test qui compte : il vérifie la propriété attendue sur n'importe quel message, sans qu'on ait à calculer le chiffré à la main. rot13 est sa propre réciproque — appliqué deux fois, il redonne le texte de départ.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.