%% 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 %%