ajout de tous les cours et TP préparés cet été
This commit is contained in:
208
Sécurité/exemples/chiffrement_ECB.py
Executable file
208
Sécurité/exemples/chiffrement_ECB.py
Executable file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Jan 8 15:27:05 2021
|
||||
|
||||
@author: pjoulaud
|
||||
"""
|
||||
from numpy.random import permutation
|
||||
# Pour créer des permutations aléatoirement
|
||||
|
||||
class ECB:
|
||||
"""
|
||||
Classe dont les instances sont des cryptosystèmes dépendant de la donnée de leur clé
|
||||
sous la forme d'une permutation
|
||||
"""
|
||||
def __init__(self, taille = None, images = None):
|
||||
"""
|
||||
Un cryptosystème ECB est défini par la donnée d'une permutation
|
||||
Une permutation a pour attributs sa taille et la liste de ses images.
|
||||
Un des deux doit être donné au moment de l'instanciation.
|
||||
Une Permutation est si besoin créée aléatoirement en utilisant la fonction permutation
|
||||
du module numpy.random
|
||||
|
||||
>>> ECB(images = [1,0,2]).images
|
||||
[1, 0, 2]
|
||||
"""
|
||||
# si les images ne sont pas données, on les tire aléatoirement
|
||||
if images :
|
||||
liste_reference = [i for i in range(len(images))]
|
||||
images_ordonnees = images[:]
|
||||
images_ordonnees.sort()
|
||||
#print(f"liste_reference {liste_reference}-images_ordonnees {images_ordonnees}")
|
||||
if images_ordonnees==liste_reference:
|
||||
self.images = images
|
||||
else :
|
||||
self.images = list(permutation(range(taille)))
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
On représente les images de la permutation :
|
||||
|
||||
>>> ECB(images=[0, 3, 2, 4, 1])
|
||||
0 3 2 4 1
|
||||
"""
|
||||
return " ".join([str(image) for image in self.images])
|
||||
|
||||
def __invert__(self) :
|
||||
"""
|
||||
Permet d'obtenir la permutation réciproque de self avec ~
|
||||
|
||||
>>> mon_ecb = ECB(images = [1,3,0,2])
|
||||
>>> mon_ecb
|
||||
1 3 0 2
|
||||
>>> ~mon_ecb
|
||||
2 0 3 1
|
||||
"""
|
||||
ma_liste = []
|
||||
for i in range(len(self.images)):
|
||||
ma_liste.append(self.images.index(i))
|
||||
mon_ecb = ECB(images=ma_liste)
|
||||
return mon_ecb
|
||||
|
||||
@property
|
||||
def taille(self):
|
||||
"""
|
||||
>>> ECB(6).taille
|
||||
6
|
||||
"""
|
||||
# si la taille n'est pas donnée, c'est la longueur de la liste des images
|
||||
return len(self.images)
|
||||
|
||||
def permute(self, une_liste):
|
||||
"""
|
||||
Permute les éléments d'une liste donnée en argument
|
||||
Si xs = [xs[0], xs[1], xs[2],...] et si p est une permutation alors
|
||||
mon_ecb.permute(xs) = [xs[p(0)], xs[p(1)], xs[p(2)],...]
|
||||
|
||||
>>> mon_ecb = ECB(images=[0, 3, 2, 4, 1])
|
||||
>>> ma_liste = ['a', 'b', 'c', 'd', 'e']
|
||||
>>> mon_ecb.permute(ma_liste)
|
||||
['a', 'd', 'c', 'e', 'b']
|
||||
"""
|
||||
if len(une_liste)>=self.taille:
|
||||
return [une_liste[i] for i in self.images]
|
||||
|
||||
def chaine2texte(self, une_chaine):
|
||||
"""
|
||||
Prend une chaine de caractères uniquement composée de 0 et de 1
|
||||
Les cryptosystèmes manipulent des chaines de bits mais les humains veulent du texte
|
||||
Cette méthode permet de transformer une trame de caractères codés sur un octet
|
||||
en la chaîne de caractères correspondante.
|
||||
|
||||
>>> mon_ecb = ECB(images=[0, 3, 2, 4, 1])
|
||||
>>> mon_ecb.chaine2texte('11101001')
|
||||
'é'
|
||||
>>> mon_ecb.chaine2texte('111010011110100111101001')
|
||||
'ééé'
|
||||
|
||||
À comparer avec :
|
||||
|
||||
>>> chr(0b11101001)
|
||||
'é'
|
||||
"""
|
||||
ma_chaine = ''
|
||||
#car_a_completer = len(une_chaine)%8
|
||||
#if car_a_completer!=0:
|
||||
# une_chaine = '0'*(8-car_a_completer)+une_chaine
|
||||
for i in range(len(une_chaine)//8):
|
||||
ma_chaine += chr(int(une_chaine[8*i:8*(i+1)],2))
|
||||
return ma_chaine
|
||||
|
||||
def texte2chaine(self, une_chaine):
|
||||
"""
|
||||
On transforme une instance de Texte en la chaîne caractères uniquement composée de 0 et de 1.
|
||||
|
||||
>>> mon_ecb = ECB(images=[0, 3, 2, 4, 1])
|
||||
>>> mon_ecb.texte2chaine('ab')
|
||||
'0110000101100010'
|
||||
>>> mon_ecb.chaine2texte(mon_ecb.texte2chaine('azerty'))
|
||||
'azerty'
|
||||
"""
|
||||
while len(une_chaine)%len(self.images) != 0:
|
||||
une_chaine += ' '
|
||||
ma_chaine = ''
|
||||
for i in une_chaine :
|
||||
for j in "{:08b}".format(ord(i)):
|
||||
ma_chaine += j
|
||||
return ma_chaine
|
||||
|
||||
def decoupe_en_blocs(self, les_caracteres):
|
||||
"""
|
||||
Prend une chaîne de caractères et la transforme en chaînes de caractères de
|
||||
longueur celle de la permutation en complétant éventuellement par des '0'.
|
||||
Méthode à usage interne facilitant l'écriture de la fonction chiffre
|
||||
|
||||
>>> mon_ecb = ECB(images=[1,0,3,2])
|
||||
>>> mon_ecb.decoupe_en_blocs('123456789123456789')
|
||||
['12345', '67891', '23456', '78900']
|
||||
"""
|
||||
ma_liste = []
|
||||
car_a_completer = len(les_caracteres)%self.taille
|
||||
if car_a_completer!=0:
|
||||
les_caracteres = '0'*(self.taille-car_a_completer) + les_caracteres
|
||||
car_a_completer = len(les_caracteres)%8
|
||||
if car_a_completer!=0:
|
||||
les_caracteres = '0'*(8-car_a_completer) + les_caracteres
|
||||
nb_car_par_elem = len(les_caracteres)//self.taille
|
||||
for i in range(self.taille):
|
||||
ma_liste.append(les_caracteres[i*nb_car_par_elem:(i+1)*nb_car_par_elem])
|
||||
return ma_liste
|
||||
|
||||
def permute(self, les_caracteres):
|
||||
"""
|
||||
Renvoie la liste des permutations des blocs de longueur celle de la permutation
|
||||
construits à partir d'une chaîne de caracteres.
|
||||
|
||||
>>> mon_ecb = ECB(images=[1,0,3,2])
|
||||
>>> mon_ecb.permute('123456789123456789')
|
||||
'67891123457890023456'
|
||||
"""
|
||||
ma_liste_de_chaine = self.decoupe_en_blocs(les_caracteres)
|
||||
#print(f"{ma_liste_de_chaine} toto")
|
||||
ma_liste_de_chaine2 = []
|
||||
for indice in self.images :
|
||||
#print(f"{une_chaine}")
|
||||
#ma_chaine = Chaine(self.cle.permute(une_chaine.entiers))
|
||||
#print(f"{ma_chaine}")
|
||||
ma_liste_de_chaine2.append(ma_liste_de_chaine[indice])
|
||||
#print(f"{ma_liste_de_chaine} - {ma_liste_de_chaine2}")
|
||||
return "".join(ma_liste_de_chaine2)
|
||||
|
||||
def chiffre(self, message):
|
||||
"""
|
||||
Retourne le message chiffré sous forme de chaîne de caracères.
|
||||
Utilise les sous-méthodes précédentes.
|
||||
|
||||
>>> mon_ecb = ECB(images=[0, 1, 3, 4, 2])
|
||||
>>> chaine_0_1 = mon_ecb.texte2chaine('hello world')
|
||||
>>> chaine_0_1_code = mon_ecb.permute(chaine_0_1)
|
||||
>>> message_code = mon_ecb.chaine2texte(chaine_0_1_code)
|
||||
|
||||
"""
|
||||
chaine_0_1 = mon_ecb.texte2chaine(message)
|
||||
#print(f"{chaine_0_1}")
|
||||
chaine_0_1_code = mon_ecb.permute(chaine_0_1)
|
||||
#print(f"{chaine_0_1_code}")
|
||||
return mon_ecb.chaine2texte(chaine_0_1_code)
|
||||
|
||||
def dechiffre(self, message_code):
|
||||
ecb_inverse = ~self
|
||||
chaine_0_1 = ecb_inverse.texte2chaine(message_code)
|
||||
print(f"0 : {chaine_0_1}")
|
||||
chaine_0_1_code = ecb_inverse.permute(chaine_0_1)
|
||||
print(f"1 : {chaine_0_1_code}")
|
||||
|
||||
return ecb_inverse.chaine2texte(chaine_0_1_code)
|
||||
|
||||
|
||||
#mon_ecb = ECB(6)
|
||||
#print(mon_ecb)
|
||||
#print(mon_ecb.taille)
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
mon_ecb = ECB(25)
|
||||
toto = mon_ecb.chiffre("Et si quelquefois, sur les marches d'un palais, sur l'herbe verte d'un fossé, vous vous réveillez, l'ivresse déjà diminuée ou disparue, demandez au vent, à la vague, à l'étoile, à l'oiseau, à l'horloge; à tout ce qui fuit, à tout ce qui gémit, à tout ce qui roule, à tout ce qui chante, à tout ce qui parle, demandez quelle heure il est. Et le vent, la vague, l'étoile, l'oiseau, l'horloge, vous répondront, il est l'heure de s'enivrer ; pour ne pas être les esclaves martyrisés du temps, enivrez-vous, enivrez-vous sans cesse de vin, de poésie, de vertu, à votre guise")
|
||||
print(toto)
|
||||
titi = mon_ecb.dechiffre(toto)
|
||||
print(titi)
|
||||
Reference in New Issue
Block a user