@@ -40,7 +40,7 @@ La classe ``CodeVigenere`` construit un objet avec les attributs ``cle`` qui con
self.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
#. Ajouter cette classe dans un notebook ou un fichier Python.
#. On souhaite ajouter une méthode ``chiffrer`` qui prend en paramètre un message écrit avec les caractères de ``alphabet`` et qui renvoie le message chiffrer.
#. On souhaite ajouter une méthode ``chiffrer`` qui prend en paramètre un message écrit avec les caractères de ``alphabet`` et qui renvoie le message chiffré.
Par exemple, on crée un objet ``CodeVigenere`` avec la clé de chiffrement ``NSI``. On chiffre le message ``BONJOUR``. On donne ci-après les instructions Python :
...
...
@@ -53,7 +53,7 @@ La classe ``CodeVigenere`` construit un objet avec les attributs ``cle`` qui con
.. note::
On peut ajouter dans la classe le code de la méthode ``decaler`` écrite pour la classe ``CodeCesar`` et l'utiliser pour effectueur les différents décalage.
On peut ajouter dans la classe le code de la méthode ``decaler`` écrite pour la classe ``CodeCesar`` et l'utiliser pour effectuer les différents décalages.
#. Écrire le code de la méthode ``dechiffrer`` qui prend en paramètre un message chiffré et qui renvoie le message initial avant le chiffrement.
{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Exercice 1\n\n1. Calculer en Python 154^45. Expliquer la valeur obtenue."},{"metadata":{"trusted":false},"cell_type":"code","source":"154^45","execution_count":1,"outputs":[{"data":{},"execution_count":1,"metadata":{},"output_type":"execute_result"}]},{"metadata":{},"cell_type":"markdown","source":"On a donc 154^45=183. Pour expliquer ce résultat, il faut convertir chaque nombre en binaire:\n\n- $154 = 128+16+8+2$ donc $154_{10} = 10011010_{2}$ \n- $45 = 32+8+4+1$ donc $45_{10} = 10011010_{2}$\n\nEn posant l'opération logique bit à bit: $10011010 \\oplus 10011010 = 10110111$\n\nEn effectuant une conversion en base 10, on obtient : $128+32+16+4+2+1=183$"},{"metadata":{},"cell_type":"markdown","source":"2. Calculer en Python A'^z. Expliquer la valeur obtenue.\n\nAvant le calcul, on doit procéder à la conversion décimale des caractère correspondant à leur écriture en binaire. Pour retrouver la valeur décimale d'un caractère, on utilise la fonction `ord` de python.\n\n- 'A' s'écrit sur 1 octet et dans la table ASCII, on a la valeur décimale : ord('A')=65\n- 'z' s'écrit sur 1 octet et dans la table ASCII, on a la valeur décimale : ord('z')=122\n\nEnsuite, on calcule 65^122 = 59\n\nPour retrouver le caractère associé à la valeur décimale 59, on utilise la fonction `chr` de Python. Finalement, on obtient le caratère point-virgule."},{"metadata":{"trusted":false},"cell_type":"code","source":"chr(ord('A')^ord('z'))","execution_count":1,"outputs":[{"output_type":"execute_result","execution_count":1,"data":{"text/plain":"';'"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"Exercice 2\n--------\n\n1. Écrire la fonction `chiffrer(msg,cle)` qui a 2 paramètres, `msg` une chaine de caractères qui est le message à chiffrer et `cle` qui est la clef de chiffrement. Cette fonction renvoie une chaine de caractères correspondant au mot chiffré avec l’opérateur XOR. \n Si la clef de chiffrement est plus courte que le message à chiffrer, celle-ci est répétée jusqu'à la fin du message.\n\n2. Chiffrer le message `BONJOUR` avec la clef de chiffrement `12xy`.\n\n3. Déchiffrer votre message chiffré et vérifier qu’on obtient bien le message initial."},{"metadata":{"trusted":false},"cell_type":"code","source":"def chiffrer(msg,cle):\n msg_chiffre = ''\n for i in range(len(msg)):\n k = i % len(cle)\n msg_chiffre += chr(ord(msg[i])^ord(cle[k]))\n return msg_chiffre\n\nm = chiffrer('BONJOUR LE MONDE','12xy')\nprint(m)\nm = chiffrer(m,'12xy')\nprint(m)","execution_count":1,"outputs":[{"output_type":"stream","text":"s}63~g*Y}wX4~|<<\nBONJOUR LE MONDE\n","name":"stdout"}]},{"metadata":{"trusted":false},"cell_type":"code","source":"chiffrer('NSI','123')","execution_count":3,"outputs":[{"output_type":"execute_result","execution_count":3,"data":{"text/plain":"'\\x7faz'"},"metadata":{}}]},{"metadata":{"trusted":false},"cell_type":"code","source":"chr(ord('N')^ord('1'))","execution_count":5,"outputs":[{"output_type":"execute_result","execution_count":5,"data":{"text/plain":"'\\x7f'"},"metadata":{}}]},{"metadata":{"trusted":false},"cell_type":"code","source":"chr(ord('S')^ord('2'))","execution_count":6,"outputs":[{"output_type":"execute_result","execution_count":6,"data":{"text/plain":"'a'"},"metadata":{}}]},{"metadata":{"trusted":false},"cell_type":"code","source":"chr(ord('I')^ord('3'))","execution_count":7,"outputs":[{"output_type":"execute_result","execution_count":7,"data":{"text/plain":"'z'"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"Exercice 3\n--------\n\nOn peut écrire un programme qui met en place les conditions du chiffrement de Vernam.\nOn convertira les chaines de caractères en binaire avec la fonction bytes. Cette fonction a 2 paramètres :\n\n- Le premier paramètre est la chaine de caractères constituant le message à convertir en binaire.\n- Le second paramètre est l’encodage à utiliser.\n\n**Exemples :**\n\n- bytes(’bonjour’,’utf8’) donne b’bonjour’\n- bytes(’bonjour’,’latin1’) donne b’bonjour’\n- bytes(’lycée’,’utf8’) donne b’lyc\\xc3\\xa9e’\n- bytes(’lycée’,’latin1’) donne b’lyc\\xe9e’\n\n1) Pourquoi y a-t-il une différence en convertissant le mot lycée et pas pour le mot bonjour ?\n2) Écrire la fonction cle_alea qui prend en paramètre une longueur de message et renvoie une clé de chiffrement\nconstitué de caractères imprimables choisis au hasard dans la table ASCII.\n3) Écrire la fonction chiffrer(msg,cle) qui a 2 paramètres, msg une chaine de caractères qui est le message à\nchiffrer et cle qui est la clef de chiffrement. Cette fonction renvoie la chaine de caractères correspondant\nau message chiffré avec l’opérateur XOR et la clé de chiffrement utilisée. Cette fonction suit l’algorithme\nsuivant :\n- On crée une chaine binaire vide renvoyée par la fonction ;\n- On convertit en binaire le message à chiffre ;\n- On crée une clé de chiffrement aléatoire de même longueur que le message convertie en binaire ;\n- Avec une boucle, on parcourt le message binaire et on lui applique le XOR avec la clé. Le résultat est\nconcaténé à la chaine binaire à renvoyer ;\n- On finit en renvoyant le message chiffré et la clé de chiffrement.\n\n4) La fonction dechiffrer(msg,cle) a deux paramètres :\n- Le message chiffré msg\n- La clé de chiffrement utilisée pour chiffre le message.\n\nCette fonction renvoie le message chiffré en clair.\n\nÉcrire le code python de cette fonction.\n\n5) Chiffrer le message ’La cryptographie symétrique est fantastique’. Vérifier ensuite que vous pouvez le déchiffrer.\n6) Recommencer avec un message contenant des caractères spéciaux et accentués.\n7) Que remarquez-vous si on utilise l’encodage UTF8 ?"},{"metadata":{"trusted":false},"cell_type":"code","source":"from random import randint\n\ndef cle_alea(longueur):\n cle = ''\n for i in range(longueur):\n cle += chr(randint(33,127))\n return cle\n\ndef chiffrer(message):\n msg_chiffre = b''\n msg = bytes(message,'latin1')\n cle = bytes(cle_alea(len(msg)),'latin1')\n for i in range(len(msg)):\n msg_chiffre += bytes(chr((msg[i]^cle[i])),'latin1')\n return (msg_chiffre,cle)\n\ndef dechiffrer(msg,key):\n msg_clair = ''\n for i in range(len(msg)):\n msg_clair += chr(msg[i]^key[i])\n return msg_clair\n\nm,k = chiffrer(\"La cryptographie est symétrique puisque la clé utilisée est la même pour chiffrer et déchiffrer\")\nprint(m)\nmsg = dechiffrer(m,k)\nprint(msg)","execution_count":5,"outputs":[{"output_type":"stream","text":"b'm&I\\\\\\x10.6=\\x00%8&,Z\\'6h;5N\\x13\\x1cU.\\xbe\\x04U\",\\x01\\\\^V+VL8I S\":\\x06W4\\xd2z\\r\\x1a_\\x01[$\\x9e,Q\\x06/G^H<u \\xcfD\\x1a\\x1e\"&E)\\x0b\\x1e\\x06>ICT;\"s.2i+\\xdc<Y\\x01<9@7V'\nLa cryptographie est symétrique puisque la clé utilisée est la même pour chiffrer et déchiffrer\n","name":"stdout"}]},{"metadata":{"trusted":false},"cell_type":"code","source":"m = bytes('bonjour','utf8')\nc = bytes(cle_alea(len('bonjour')),'utf8')\nprint(m,c)","execution_count":5,"outputs":[{"output_type":"stream","text":"b'bonjour' b'OGOP)YX'\n","name":"stdout"}]},{"metadata":{"trusted":false},"cell_type":"code","source":"e = b''\nfor i in range(len(m)):\n e += bytes(chr(m[i]^c[i]),'utf8')\nprint(e)","execution_count":13,"outputs":[{"output_type":"stream","text":"b'-(!:F,*'\n","name":"stdout"}]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"}},"nbformat":4,"nbformat_minor":2}
\ No newline at end of file
%% Cell type:markdown id: tags:
# Exercice 1
1. Calculer en Python 154^45. Expliquer la valeur obtenue.
%% Cell type:code id: tags:
``` python
154^45
```
%% Output
%% Cell type:markdown id: tags:
On a donc 154^45=183. Pour expliquer ce résultat, il faut convertir chaque nombre en binaire:
- $154 = 128+16+8+2$ donc $154_{10} = 10011010_{2}$
- $45 = 32+8+4+1$ donc $45_{10} = 10011010_{2}$
En posant l'opération logique bit à bit: $10011010 \oplus 10011010 = 10110111$
En effectuant une conversion en base 10, on obtient : $128+32+16+4+2+1=183$
%% Cell type:markdown id: tags:
2. Calculer en Python A'^z. Expliquer la valeur obtenue.
Avant le calcul, on doit procéder à la conversion décimale des caractère correspondant à leur écriture en binaire. Pour retrouver la valeur décimale d'un caractère, on utilise la fonction `ord` de python.
- 'A' s'écrit sur 1 octet et dans la table ASCII, on a la valeur décimale : ord('A')=65
- 'z' s'écrit sur 1 octet et dans la table ASCII, on a la valeur décimale : ord('z')=122
Ensuite, on calcule 65^122 = 59
Pour retrouver le caractère associé à la valeur décimale 59, on utilise la fonction `chr` de Python. Finalement, on obtient le caratère point-virgule.
%% Cell type:code id: tags:
``` python
chr(ord('A')^ord('z'))
```
%% Output
';'
%% Cell type:markdown id: tags:
Exercice 2
--------
1. Écrire la fonction `chiffrer(msg,cle)` qui a 2 paramètres, `msg` une chaine de caractères qui est le message à chiffrer et `cle` qui est la clef de chiffrement. Cette fonction renvoie une chaine de caractères correspondant au mot chiffré avec l’opérateur XOR.
Si la clef de chiffrement est plus courte que le message à chiffrer, celle-ci est répétée jusqu'à la fin du message.
2. Chiffrer le message `BONJOUR` avec la clef de chiffrement `12xy`.
3. Déchiffrer votre message chiffré et vérifier qu’on obtient bien le message initial.
%% Cell type:code id: tags:
``` python
defchiffrer(msg,cle):
msg_chiffre=''
foriinrange(len(msg)):
k=i%len(cle)
msg_chiffre+=chr(ord(msg[i])^ord(cle[k]))
returnmsg_chiffre
m=chiffrer('BONJOUR LE MONDE','12xy')
print(m)
m=chiffrer(m,'12xy')
print(m)
```
%% Output
s}63~g*Y}wX4~|<<
BONJOUR LE MONDE
%% Cell type:code id: tags:
``` python
chiffrer('NSI','123')
```
%% Output
'\x7faz'
%% Cell type:code id: tags:
``` python
chr(ord('N')^ord('1'))
```
%% Output
'\x7f'
%% Cell type:code id: tags:
``` python
chr(ord('S')^ord('2'))
```
%% Output
'a'
%% Cell type:code id: tags:
``` python
chr(ord('I')^ord('3'))
```
%% Output
'z'
%% Cell type:markdown id: tags:
Exercice 3
--------
On peut écrire un programme qui met en place les conditions du chiffrement de Vernam.
On convertira les chaines de caractères en binaire avec la fonction bytes. Cette fonction a 2 paramètres :
- Le premier paramètre est la chaine de caractères constituant le message à convertir en binaire.
- Le second paramètre est l’encodage à utiliser.
**Exemples :**
- bytes(’bonjour’,’utf8’) donne b’bonjour’
- bytes(’bonjour’,’latin1’) donne b’bonjour’
- bytes(’lycée’,’utf8’) donne b’lyc\xc3\xa9e’
- bytes(’lycée’,’latin1’) donne b’lyc\xe9e’
1) Pourquoi y a-t-il une différence en convertissant le mot lycée et pas pour le mot bonjour ?
2) Écrire la fonction cle_alea qui prend en paramètre une longueur de message et renvoie une clé de chiffrement
constitué de caractères imprimables choisis au hasard dans la table ASCII.
3) Écrire la fonction chiffrer(msg,cle) qui a 2 paramètres, msg une chaine de caractères qui est le message à
chiffrer et cle qui est la clef de chiffrement. Cette fonction renvoie la chaine de caractères correspondant
au message chiffré avec l’opérateur XOR et la clé de chiffrement utilisée. Cette fonction suit l’algorithme
suivant :
- On crée une chaine binaire vide renvoyée par la fonction ;
- On convertit en binaire le message à chiffre ;
- On crée une clé de chiffrement aléatoire de même longueur que le message convertie en binaire ;
- Avec une boucle, on parcourt le message binaire et on lui applique le XOR avec la clé. Le résultat est
concaténé à la chaine binaire à renvoyer ;
- On finit en renvoyant le message chiffré et la clé de chiffrement.
4) La fonction dechiffrer(msg,cle) a deux paramètres :
- Le message chiffré msg
- La clé de chiffrement utilisée pour chiffre le message.
Cette fonction renvoie le message chiffré en clair.
Écrire le code python de cette fonction.
5) Chiffrer le message ’La cryptographie symétrique est fantastique’. Vérifier ensuite que vous pouvez le déchiffrer.
6) Recommencer avec un message contenant des caractères spéciaux et accentués.
7) Que remarquez-vous si on utilise l’encodage UTF8 ?
%% Cell type:code id: tags:
``` python
fromrandomimportrandint
defcle_alea(longueur):
cle=''
foriinrange(longueur):
cle+=chr(randint(33,127))
returncle
defchiffrer(message):
msg_chiffre=b''
msg=bytes(message,'latin1')
cle=bytes(cle_alea(len(msg)),'latin1')
foriinrange(len(msg)):
msg_chiffre+=bytes(chr((msg[i]^cle[i])),'latin1')
return (msg_chiffre,cle)
defdechiffrer(msg,key):
msg_clair=''
foriinrange(len(msg)):
msg_clair+=chr(msg[i]^key[i])
returnmsg_clair
m,k=chiffrer("La cryptographie est symétrique puisque la clé utilisée est la même pour chiffrer et déchiffrer")