%% nav-debut : généré par gen_navigation.py, ne pas modifier à la main %% > [!nav] > ↩ [[Code et Développement/Programmation/Cryptographie/Cryptographie|Accueil · Cryptographie]] > > | [[Code et Développement/Programmation/Cryptographie/03_Permutation alphabétique\|← Permutation alphabétique]] | [[Code et Développement/Programmation/Cryptographie/05_Algorithme RSA\|Algorithme RSA →]] | > |:---|---:| %% nav-fin %% # Le chiffre de Vigenère Les notions de chiffrement, de clé et d'indice d'une lettre sont présentées dans la page [[Code et Développement/Programmation/Cryptographie/01_ROT13|ROT13]]. ## Le principe Le chiffre de Vigenère est une substitution **polyalphabétique**. La clé est un mot. Chaque lettre du texte est décalée de l'indice de la lettre de clé qui lui correspond. La clé est répétée autant de fois que nécessaire. Avec la clé « super », la première lettre est décalée de s, la deuxième de u, la troisième de p, et ainsi de suite. Une même lettre claire peut donc donner des lettres chiffrées différentes. Deux lettres chiffrées identiques peuvent venir de lettres claires différentes. L'analyse de fréquences, efficace contre la [[Code et Développement/Programmation/Cryptographie/03_Permutation alphabétique|permutation alphabétique]], ne fonctionne plus directement. ## Chiffrer une lettre Pour chiffrer la lettre j avec la lettre de clé s, on additionne leurs indices, puis on applique le modulo 26. ```python from string import ascii_lowercase, ascii_uppercase lower = ascii_lowercase upper = ascii_uppercase i_lettre = lower.index('j') # 9 i_cle = lower.index('s') # 18 i_code = (i_lettre + i_cle) % 26 # 27 % 26 = 1 print(lower[i_code]) # b ``` ## Répéter la clé Le caractère d'indice `i` du texte utilise la lettre de clé d'indice `i % len(cle)`. Avec la clé « super », de longueur 5, le caractère d'indice 11 utilise la lettre d'indice 11 % 5 = 1, soit u. ```python i_texte = 11 cle = 'super' print(i_texte % len(cle)) # 1 ``` Dans la fonction du cours, l'indice `i` parcourt tous les caractères du texte. La clé avance donc aussi sur les espaces et la ponctuation. D'autres versions ne font avancer la clé que sur les lettres : le texte chiffré est alors différent. ## Les fonctions de chiffrement et de déchiffrement ```python def vigenere(x, cle): """Renvoie x chiffré avec le chiffre de Vigenère et la clé cle (en minuscules).""" code = "" for i in range(len(x)): decalage = lower.index(cle[i % len(cle)]) if x[i] in lower: code += lower[(lower.index(x[i]) + decalage) % 26] elif x[i] in upper: code += upper[(upper.index(x[i]) + decalage) % 26] else: code += x[i] return code print(vigenere("j'aime le python", 'super')) # b'pmdw ai hsilff ``` Le déchiffrement est identique, avec une soustraction à la place de l'addition : ```python code += lower[(lower.index(x[i]) - decalage) % 26] ``` La clé doit être écrite en minuscules, sans espace ni accent : `lower.index` échoue sur tout autre caractère. **À manipuler :** suivez le chiffrement lettre par lettre avec « Lettre ▶ ». « Déchiffrer » reprend le texte chiffré et retrouve le texte clair. Ce bloc suit la convention du cours : la clé avance sur chaque caractère. ```sq-vigenere texte: j'aime le python clé: super clé sur: tout ``` Dans « b'pmdw ai hsilff », les deux e de « j'aime le » donnent w et i. Les deux f finaux viennent de o et de n. %% nav-debut : généré par gen_navigation.py, ne pas modifier à la main %% > [!nav] > ↩ [[Code et Développement/Programmation/Cryptographie/Cryptographie|Accueil · Cryptographie]] > > | [[Code et Développement/Programmation/Cryptographie/03_Permutation alphabétique\|← Permutation alphabétique]] | [[Code et Développement/Programmation/Cryptographie/05_Algorithme RSA\|Algorithme RSA →]] | > |:---|---:| %% nav-fin %%