Aller au contenu

Chiffrement de Vigenère

I. Le principe⚓︎

Vigenere

Un exemple de chiffrement symétrique

Le chiffre de Vigenère a été proposé il y a un peu moins de 500 ans, et utilise la même idée que le chiffrement de César, mais en la complexifiant beaucoup.

Avant de démarrer

Vous pouvez commencer par résoudre l'exercice suivant :

Le chiffre de César

Mon info

Le chiffre de Vigenère a été proposé il y a un peu moins de 500 ans. C'est un système de chiffrement par substitution qui consiste à coder un texte à l’aide d’une clé donnée cette fois sous forme de texte (plus court généralement) : la première lettre du texte à coder est décalée d'un entier correspondant au premier caractère de la clé et ainsi de suite. Si la clé est plus courte que le texte à coder, elle est répétée..

La correspondance entre les lettres et les nombres associés est donnée dans le tableau suivant :

a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

Exemple

Schématisons cela. Nous allons chiffrer le mot incroyable avec la clef nsi.
On répète la clef pour créer une clef de même longueur que le texte à chiffrer :

i n c r o y a b l e
n s i n s i n s i n

En utilisant le tableau précédant, nous obtenons donc :

lettre i n c r o y a b l e
entier associé 8 13 2 17 14 24 0 1 11 4
décalage à effectuer 13 18 8 13 18 8 13 18 8 13
entier pour chiffrement 21 31 10 30 32 32 13 19 19 17

Nous observons que l'on peut obtenir un nombre supérieur à 25. On trouve alors la lettre correspondante en "bouclant" sur l'alphabet. 26 correspond à la lettre "a", 27 à "b" etc. Pour trouver la lettre associée à un enier n, il suffit de regarder la lettre associée à l'entier n % 26

Nous obtenons donc :

lettre i n c r o y a b l e
entier associé 8 13 2 17 14 24 0 1 11 4
décalage à effectuer 13 18 8 13 18 8 13 18 8 13
entier pour chiffrement 21 5 10 4 6 6 13 19 19 17
lettre chiffrée v f k e g g n t r

Remarquons que des lettres différentes peuvent être chiffrées par la même, ce qui rend le décryptage difficile.

II. Exercices⚓︎

correspondance nombre - lettre

Compléter le script suivant qui permet de constituer le dictionnaire nombre_lettredont voici un extrait :

nombre_lettre = {0: 'a', 1: 'b', 2: 'c', 3: 'd', etc...}

###
# Testbksl-nlassert nombrepy-undlettre == {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'mbksl-nl', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24:bksl-nl 'y', 25: 'z'}bksl-nlbksl-nl# Autres testsbksl-nlassert nombrepy-undlettre[1] == "b"bksl-nlbksl-nl 5/5
def creepy-undnombrepy-undlettre():bksl-nl ...bksl-nlbksl-nlbksl-nlnombrepy-undlettre = creepy-undnombrepy-undlettre()bksl-nlbksl-nl# Testbksl-nlassert nombrepy-undlettre[0] == "a"bksl-nlbksl-nldef creepy-undnombrepy-undlettre():bksl-nl dico = {}bksl-nl for i in range(26):bksl-nl dico[i]= chr(97 + i)bksl-nl return dicobksl-nlbksl-nl


😊 On peut aussi créer le dictionnaire en compréhension :

🐍 Script Python
def cree_nombre_lettre():
    return {i: chr(97 + i) for i in range(26)}

correspondance lettre - nombre

Compléter le script suivant qui permet de constituer le dictionnaire lettre_nombredont voici un extrait :

lettre_nombre = {'a': 0, 'b': 1, 'c': 2, 'd': 3, etc...}

###
# Testbksl-nlassert lettrepy-undnombre == {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 1bksl-nl2, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y'bksl-nl: 24, 'z': 25}bksl-nlbksl-nl# Autres testsbksl-nlassert lettrepy-undnombre["b"] == 1bksl-nlbksl-nl 5/5
def creepy-undlettrepy-undnombre() :bksl-nl ...bksl-nlbksl-nlbksl-nl# Testbksl-nllettrepy-undnombre = creepy-undlettrepy-undnombre()bksl-nlassert lettrepy-undnombre["a"] == 0bksl-nlbksl-nldef creepy-undlettrepy-undnombre() :bksl-nl lettrepy-undnombre = {}bksl-nl for i in range(26):bksl-nl lettrepy-undnombre[chr(i + 97)] = ibksl-nl return lettrepy-undnombrebksl-nlbksl-nlbksl-nl


😊 On peut aussi créer le dictionnaire en compréhension :

🐍 Script Python
def cree_lettre_nombre():
    return {chr(i + 97): i for i in range(26)}

Chiffrement de Vigenère

Compléter le script suivant :

###
# Testbksl-nlassert chiffrepy-undvigenere('incroyable','nsi') == 'vfkeggnttr'bksl-nlassert chiffrepy-undvigenere('incroyable','a') == 'incroyable'bksl-nlbksl-nl# Autres testsbksl-nlassert chiffrepy-undvigenere('hello','nsi') == "uwtyg"bksl-nlbksl-nlbksl-nl 5/5
def chiffrepy-undvigenere(texte: str, clef: str ) -> str :bksl-nl """bksl-nl Préconditions :bksl-nl - texte est le texte à chiffrer (type str)bksl-nl - clef est la clef (type str)bksl-nl Postconditions :bksl-nl la fonction renvoie le texte chiffré : type str.bksl-nl Par exemple chiffrepy-undvigenere('incroyable','nsi') renvoie 'vfkeggnttr'bksl-nl """bksl-nlbksl-nl ...bksl-nlbksl-nlnombrepy-undlettre = creepy-undnombrepy-undlettre() # nombrepy-undlettre = {0: 'a', 1: 'b', 2: 'c',bksl-nl # 3: 'd', etc...}bksl-nllettrepy-undnombre = creepy-undlettrepy-undnombre() # lettrepy-undnombre = {'a': 0, 'b': 1, 'c': 2,bksl-nl # 'd': 3, etc...}bksl-nlbksl-nl# Testbksl-nlassert chiffrepy-undvigenere('incroyable','nsi') == 'vfkeggnttr'bksl-nlassert chiffrepy-undvigenere('incroyable','a') == 'incroyable'bksl-nldef chiffrepy-undvigenere(texte: str, clef: str ) -> str :bksl-nl textepy-undchiffre = ""bksl-nl for i in range(len(texte)) :bksl-nl lettre = texte[i]bksl-nl indicepy-undclef = i % len(clef)bksl-nl lettrepy-unddecalage = clef[indicepy-undclef]bksl-nl decalage = lettrepy-undnombre[lettrepy-unddecalage]bksl-nl nombre = (lettrepy-undnombre[lettre] + decalage) % 26bksl-nl lettrepy-undchiffree = nombrepy-undlettre[nombre]bksl-nl textepy-undchiffre = textepy-undchiffre + lettrepy-undchiffreebksl-nl return textepy-undchiffrebksl-nlbksl-nlbksl-nlbksl-nl