Pour commencer, un petit rappel sur ce qu’est le chiffre de César. Il s’agit d’une technique de chiffrement très simple, consistant à décaler les lettres de l’alphabet d’un nombre de crans.
Par exemple, si on dit que le décalage est de 4, « a » devient « e », « b » devient « f », « c » devient « g », etc…
Comment le faire en Python ?
Comme ici chaque lettre est toujours remplacée par la même, il y a une fonction parfaite pour ça : str.translate().
Cette fonction prend pour paramètre une table de traduction, générée par str.maketrans(), qui elle prend en paramètres deux chaînes de caractères :
- les lettres de départ, dans notre cas l’alphabet
- les lettres de remplacement, dans l’ordre, c’est-à-dire qu’avec « abc… » au départ, et un décalage de 4, la chaîne de remplacement est « efg… »
Bon, c’est bien sympa ce principe, mais comment on fait concrètement ?
Le point le plus compliqué reste la construction de l’alphabet décalé. Pour ça, il faut utiliser les slices de chaînes.
Pour rappel, les slices permettent de ne récupérer qu’une partie d’une chaîne. Leur syntaxe est ma_chaine[<index de départ>:<index d'arrivé (non inclus)>:<décalage>].
Par exemple :
alphabet = 'abcdefghijklmnopqrstuvwxyz'
alphabet[2:5] # 'cde'
alphabet[0:5] # 'abcde'
alphabet[0:5:2]
Je n’ai fait ici qu’une présentation rapide. Pour en savoir plus sur les slices, allez voir la doc Python.
Dans notre cas, pour construire l’alphabet décalé, il faut d’abord prendre la partie de l’index du décalage jusqu’à la fin, et lui coller après la partie du début jusqu’à l’index du décalage.
Ce qui en code donne :
alphabet_decale = alphabet[decalage:] + alphabet[:decalage]
Une fois l’alphabet décalé généré, il ne reste plus qu’à créer la table de traduction, et l’utiliser avec .translate() sur le texte de départ.
table_de_correpondances = str.maketrans(alphabet, alphabet_decale)
texte_cesar = texte.translate(table_de_correspondances)
Et voilà ^^
Le code donné en exemple permet de coder, pour décoder, il suffit d’inverser les deux paramètre de str.maketrans().
En emballant tout ça dans une belle fonction, et en rajoutant les majuscules, cela nous donne :
def caesar_cypher(shift: int, txt: str, encode: Boolean = False) -> str:
alphabet = 'abcdefghijklmnopqrstuvwxyz'
full_alphabet = alphabet + alphabet.upper()
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
full_shifted_alphabet = shifted_alphabet + shifted_alphabet.upper()
if encode is True:
translation_table = str.maketrans(full_alphabet, full_shifted_alphabet)
else:
translation_table = str.maketrans(full_shifted_alphabet, full_alphabet)
return txt.translate(translation_table)