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.