Aller au contenu

(Dé)codage, (dé)chiffrement

Codage, décodage : exemple du code ASCII

L'American Standard Code for Information Interchange (Code américain normalisé pour l'échange d'information), plus connu sous l'acronyme ASCII, est une norme informatique de codage de caractères apparue dans les années 1960. C'est la norme de codage de caractères la plus influente à ce jour. ASCII définit 128 codes à 7 bits, comprenant 95 caractères imprimables : les chiffres arabes de 0 à 9, les 26 lettres de l'alphabet latin en minuscules et en capitales, et des symboles mathématiques et de ponctuation.

Le code ASCII est donc une référence commune. En python, il existe deux fonctions permettant de manipuler les caractères :

  • ord qui étant donné un caractère (une chaîne de caractères de taille 1) renvoie son code ASCII (notation décimale).
  • chr qui étant donné un entier renvoie le caractère de la table ASCII correspondant.

Ainsi, tout le monde peut encoder une chaîne de caractères suivant le code ASCII, et décoder une chaîne de caractères suivant le code ASCII.

Codage d'un texte

Écrire une fonction code_ascii qui étant donné une chaîne de caractères, renvoie une liste d'entiers correspondant aux codes ASCII de ces caractères.

###
def testpy-undcodepy-undascii():bksl-nl """ Tests pour la fonction codepy-undascii """bksl-nl print("Tests de codepy-undascii passés avec succès.")bksl-nl return Truebksl-nlbksl-nl# from tp import codepy-undasciibksl-nl# testpy-undcodepy-undascii()bksl-nlbksl-nl 5/5

def codepy-undascii(texte):bksl-nl """ str -> [int]bksl-nl Renvoie la liste des codes ascii des caractères du texte """bksl-nl passbksl-nlbksl-nl

Décodage d'un texte

Écrire une fonction décode_ascii qui étant donné une liste d'entiers correspondant à des codes ASCII, renvoie la chaîne de caractères correspondante.

###
def testpy-unddecodepy-undascii():bksl-nl """ Tests pour la fonction decodepy-undascii """bksl-nl print("Tests de decodepy-undascii passés avec succès.")bksl-nl return Truebksl-nlbksl-nl# from tp import decodepy-undasciibksl-nl# testpy-unddecodepy-undascii()bksl-nlbksl-nl 5/5

def decodepy-undascii(codes):bksl-nl """ [int] -> strbksl-nl Renvoie la chaîne de caractères correspondant aux codes ascii """bksl-nl passbksl-nlbksl-nl

Génération de l'alphabet

Écrire une fonction genere_alphabet_majuscule qui renvoie la liste des 26 lettres de l'alphabet latin en majuscule.

###
def testpy-undgenerepy-undalphabetpy-undmajuscule():bksl-nl """ Tests pour la fonction generepy-undalphabetpy-undmajuscule """bksl-nl print("Tests de generepy-undalphabetpy-undmajuscule passés avec succès.")bksl-nl return Truebksl-nlbksl-nl# from tp import generepy-undalphabetpy-undmajusculebksl-nl# testpy-undgenerepy-undalphabetpy-undmajuscule()bksl-nlbksl-nl 5/5

def generepy-undalphabetpy-undmajuscule():bksl-nl """ () -> [str]bksl-nl Renvoie la liste des 26 lettres de l'alphabet latin en majuscule """bksl-nl passbksl-nlbksl-nl

Chiffrement, déchiffrement

Il y deux types de cryptographie dans ce monde : la cryptographie qui empêche votre petite sœur de lire vos fichiers, et la cryptographie qui empêche le gouvernement de lire vos fichiers.

La méthode de chiffrement de César

L'une des méthodes les plus anciennes pour chiffrer un texte est attribuée à Jules César. Elle consiste à remplacer chaque lettre du message par la lettre située trois places plus loin dans l'alphabet. Par analogie, on continue d'appeler cette méthode un chiffrement de César si le décalage vaut autre chose que 3. On appelle le premier message le clair et celui obtenu après décalage le chiffré.

On considère dans cette partie que l'on ne chiffre que des lettres majuscules non accentuées, les autres caractères (ponctuation, espaces, chiffres) restent inchangés.

    1. En considérant un décalage de 3, chiffrer le texte TG8 WINZALL.
    2. De combien de manières possibles peut-on chiffrer un texte avec la méthode de chiffrement de César ?
  1. De quelle(s) information(s) a-t-on besoin pour déchiffrer un message ? Déchiffrer le mot LQIRUPDWLTXH<3.

Décalage de caractère

Écrire une fonction decale_car qui étant donné un caractère car et une valeur de décalage cle renvoie le caractère décalé correspondant si car est un caractère majuscule. Si car n'est pas un caractère majuscule, alors la fonction renverra car.

Ainsi, avec une valeur de décalage de 3, 'A' sera chiffré en 'D', 'B' sera chiffré en 'E', etc.

Indication.. Afin de déterminer la relation entre car, cle et decale_car(car, cle), on pourra utiliser le tableau ci-dessus, en explicitant quelle fonction permet de passer d'une ligne à la suivante.

img

Par exemple, on passe de la ligne 1 du tableau à la ligne 2 du tableau en appliquant ord au caractère car. On rappelle également un exemple d'utilisation de la fonction modulo % :

1
2
for i in range(10):
    print(i%4, end = '')
0123012301
###
def testpy-unddecalepy-undcar():bksl-nl """ Tests pour la fonction decalepy-undcar """bksl-nl print("Tests de decalepy-undcar passés avec succès.")bksl-nl return Truebksl-nlbksl-nl# from tp import decalepy-undcarbksl-nl# testpy-unddecalepy-undcar()bksl-nlbksl-nl 5/5

def decalepy-undcar(car, cle):bksl-nl """ str, int -> strbksl-nl Si car est une majuscule,bksl-nl renvoie le caractère correspondant à car, décalé de cle """bksl-nl if not ord('A') <= ord(car) <= ord('Z'):bksl-nl return ...bksl-nl res = ord(car) bksl-nl # à compléterbksl-nlbksl-nl

Chiffrement de César

Écrire une fonction chiffre_cesar qui étant donné un texte en clair et une cle applique la méthode de chiffrement de César au clair avec un décalage égal à la cle.

###
def testpy-undchiffrepy-undcesar():bksl-nl """ Tests pour la fonction chiffrepy-undcesar """bksl-nl print("Tests de chiffrepy-undcesar passés avec succès.")bksl-nl return Truebksl-nlbksl-nl# from tp import chiffrepy-undcesarbksl-nl# testpy-undchiffrepy-undcesar()bksl-nlbksl-nl 5/5

def chiffrepy-undcesar(clair, cle):bksl-nl """ str, int -> strbksl-nl Chiffre le clair avec le chiffrement de César (cle = décalage) """bksl-nl passbksl-nlbksl-nl

Déchiffrement de César

Écrire une fonction dechiffe_cesar qui étant donné un message chiffre avec une cle renvoie le texte en clair correspondant.

###
def testpy-unddechiffrepy-undcesar():bksl-nl """ Tests pour la fonction dechiffrepy-undcesar """bksl-nl print("Tests de dechiffrepy-undcesar passés avec succès.")bksl-nl return Truebksl-nlbksl-nl# from tp import dechiffrepy-undcesarbksl-nl# testpy-unddechiffrepy-undcesar()bksl-nlbksl-nl 5/5

def dechiffrepy-undcesar(chiffre, cle):bksl-nl """ str, int -> strbksl-nl Renvoie le texte clair vérifiant chiffre = chiffrepy-undcesar(clair, cle) """bksl-nl passbksl-nlbksl-nl

Une petite énigme

Entre deux toiles d'araignées, vous trouvez dans le grenier de votre grand-mère, agent secrète pour le compte des britanniques lors de la seconde guerre mondiale, une malle antique remplie de documents. Intrigué·e vous en parcourez du regard quelques uns.

LE 26 AVRIL 1942, A WASHINGTON D.C.

A QUI DE DROIT,
J'AI FAIT DES DECOUVERTES IMPORTANTES SUR LA CRYPTANALYSE DE LA MACHINE ENIGMA. J'AI UTILISE MES CONNAISSANCES ET CRYPTOGRAPHIE ANTIQUE POUR PROTEGER MES TRAVAUX DES PLUS CURIEUX, MAIS JE N'AI AUCUN DOUTE QU'UN EXPERT EN CRYPTOGRAPHIE SAURA Y ACCÉDER.

ELIZABETH SMITH FRIEDMAN.
POST-SCRIPTUM : PORTEZ CE VIEUX WISKY AU JUGE BLOND QUI FUME.

Vous finissez par tomber sur ce document, qui vous laisse perplexe.

OH 28 DYULO 1942, D ZDVKLQJWRQ G.F.

D TXL GH GURLW.
PD GHFRXYHUWH SRUWH VXU OD VWUXFWXUH GH OD PDFKLQH HQLJPD. HOOH SHUPHW GH IDLUH GHV VXFFHVVLRQV GH VXEVWLWXWLRQV HW GH SHUPXWDWLRQV. M'DL DXVVL O'LPSUHVVLRQ TXH OD VWUXFWXUH GHV PHVVDJHV HFKDQJHV HVW VRXYHQW OD PHPH, FH TXH QRXV DOORQV WHQWHU G'HASORLWHU.

HOLCDEHWK VPLWK IULHGPDQ.
SRVW-VFULSWXP : SRUWHC FH YLHXA ZLVNB DX MXJH EORQG TXL IXPH. 
  1. Quel(s) point(s) commun(s) pouvez-vous imaginer entre le message chiffré et le message en clair connu ?
  2. À l'aide des fonctions écrites précédemment, déchiffrer le texte chiffré. De quelle information avez-vous eu besoin ?

La méthode de chiffrement de Vigenère

Le chiffrement de César n'est pas un chiffrement très sécurisé :

  • il n'y a que 26 clé possibles, ce qui le rend vulnérable aux attaques par force brute ;
  • une fois que la clé a été choisie, chaque lettre de l'alphabet est toujours chiffrée de la même manière : on parle de chiffrement mono-alphabetique. Ceci le rend vulnérable à une attaque par analyse des fréquences.

Une de ses variantes est le chiffrement de Vigenère. Cette méthode consiste à exploiter l'ensemble des 26 chiffrements de César possibles, que l'on stocke dans une table appelée carré de Vigenère :

img

La clé n'est alors plus un seul entier, mais une liste d'entiers i avec \(0 \leq i < 26\) qui indique quel alphabet de chiffrement utiliser pour chaque lettre du message clair. On dira que la taille de la clé est le nombre d'entiers qui la composent. Chaque caractère du texte en clair est alors chiffré à l'aide du chiffrement de César avec le morceau de la clé correspondant.

Par exemple, si le message est 'LA RELEVE ARRIVE' et que la clé est [19, 20, 17, 8, 13, 6], on chiffre le premier caractère 'L' avec un chiffrement de César et un décalage de 19 : on obtient la lettre 'E'. On chiffre le second caractère 'A' avec un chiffrement de César et un décalage de 20, etc. Comme la clé est en générale plus courte que le message à chiffrer, on répète la clé autant de fois que nécessaire.

img

Remarque. Afin de mémoriser cette suite d'entiers, on peut lui associer un mot-clé. Par exemple, le moyen mnémotechnique pour mémoriser la clé [19, 20, 17, 8, 13, 6] est d'utiliser le mot 'TURING' : 'T' est la 19ième lettre de l'alphabet, U la 20ième, etc.

1
2
3
4
5
6
7
def indice_lettre(c):
    """ str -> int
    Renvoie l'indice dans l'alphabet de la lettre capitale c. """
    return ord(c) - ord('A')

cle = [indice_lettre(c) for c in "TURING"]
print(cle)
[19, 20, 17, 8, 13, 6]

Chiffrer le message TENEZ BON ! à l'aide du chiffrement de Vigenère en utilisant la clé NSI.

Fonction de chiffrement

Écrire une fonction chiffre_vigenere qui étant donné un texte clair et une cle renvoie le texte chiffré que l'on obtient à l'aide de la méthode de chiffrement de Vigenère.

Indication. Vous utiliserez pour cela la fonction chiffre_cesar. Afin de "mettre bout à bout suffisamment de fois" la clé, on pourra utiliser au choix l'une des deux informations suivantes :

  • [i%4 for i in range(10)] s'évalue en [0,1,2,3,0,1,2,3,0,1] ;
  • [1, 2, 3]*4 s'évalue en [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3].
###
def testpy-undchiffrepy-undvigenere():bksl-nl """ Tests pour la fonction chiffrepy-undvigenere """bksl-nl print("Tests de chiffrepy-undvigenere passés avec succès.")bksl-nl return Truebksl-nlbksl-nl# from tp import chiffrepy-undvigenerebksl-nl# testpy-undchiffrepy-undvigenere()bksl-nlbksl-nl 5/5

def chiffrepy-undvigenere(clair, cle):bksl-nl """ str, [int] -> strbksl-nl Chiffrement de Vigenère """bksl-nl passbksl-nlbksl-nl