TDK2 : Codage/décodage d'une image par masque XOR¶

1. Rappel sur l'opérateur binaire XOR (ou exclusif)¶

Q1. Compléter la table de vérité de l'opérateur XOR :

x y x XOR y
0 0 0
0 1 ...
1 0 ...
1 1 ...

Q2. Même chose avec des nombres entiers. Après avoir converti 5 et 3 en binaire, donner l'écriture décimale de 5 XOR 3 :

Réponse :

In [ ]:
# vérifier votre réponse avec python sachant que l'opérateur XOR est le ^

Q3a. Que vaut : (5 XOR 3) XOR 3 = .....

In [ ]:
# vérfier votre réponse avec python :

Q3b. Plus généralement si x et y sont deux entiers, que vaut : (x XOR y) XOR y = .....

C'est cette propriété qui est à la base de la méthode de cryptographie utilisée dans ce travail

2. Méthode de cryptage/décryptage¶

Expliquons la méthode retenue sur un exemple simple, que l'on traitera à la main, sur un papier quadrillé.

Considérons les trois images de taille 5x5 suivantes:

principe_cryptage_xor.png

La première est l'image originale que l'on souhaite crypter, la seconde est un masque jetable (appelé aussi clé) qui est obtenu par la génération aléatoire de 25 chiffres 0 ou 1. La troisième, qui représente l'image cryptée est obtenue en appliquant l'opérateur XOR entre les deux premières images.

Q4a. D'après les résultats rappelés en première partie pensez-vous que l'on puisse retrouver l'image originale uniquement à partir du masque jetable et de l'image codée ? Si oui comment faire ?

Réponse : ....

Q4b. À la main, sur une feuille quadrillée, appliquer l'opérateur XOR entre l'image cryptée et le masque jetable. Que constatez-vous ? Cela confirme-t-il votre réponse à la question précédente ?

Réponse : ...

3. Solution programmée¶

!!! note À noter

dans le TD précédent, on a travaillé à partir d'un image au format jpg. Les valeurs des pixels étaient des entiers compris entre 0 et 255 (en fait des triplets lorsque l'image était en couleur). Ici pour changer, on va travailller sur une image au format png. Ce qui change, c'est que les valeurs des pixels sont des flottants compris entre 0 et 1. C'est pour cela que l'on commence par convertir ces nombres en entiers de 0 à 255.

!!!

On donne ci-dessous les instructions qui permettent de charger et afficher l'image cryptée et le masque jetable

In [ ]:
# les bibliothèques que l'on va utiliser

import matplotlib.pyplot as plt
import matplotlib.image as iplt
import numpy as np

# chargement des images et conversion des nombres flottants entre 0 et 1 en nombres entiers entre 0 et 255
codee = (iplt.imread('image_codee.png')*255).astype(np.int32)
masque = (iplt.imread('image_masque.png')*255).astype(np.int32)

# affichage avec subfigure
plt.figure(1)
plt.clf()
plt.subplot(121)
plt.imshow(codee,cmap='gray',vmin=0,vmax=255)
plt.title('image codée')
plt.subplot(122)
plt.imshow(masque,cmap='gray',vmin=0,vmax=255)
plt.title('masque')
plt.show()

!!! note À noter ! Après avoir exécuté la cellule précédente, les images sont stockées dans les variables codee pour l'image cryptée et masque pour le masque jetable. !!!

In [ ]:
# Important : fonction d'affichage d'une image (comme dans le TD précédent)
def display(tab, fig = 2):
    plt.figure(fig)
    plt.clf()
    plt.imshow(tab,cmap='gray',vmin=0,vmax=255) # on crée en mémoire la figure (comme d'habitude ave plt.plot)
    plt.show() # on affiche la figure à l'écran.

Q5. Proposer une fonction decodage(im_cryptee,masque) qui reçoit une image cryptée et un masque et qui procède au décodage, c'est à dire qui renvoie l'image originale.

On notera que l'opérateur binaire XOR en python est l'accent circonflèxe ^ ( a XOR b s'écrit donc en python a^b)

In [ ]:
# Décodage version 1:
    
def decodage1(image,masque):
    XMAX,YMAX = np.shape(image)
    im_finale = np.zeros((XMAX,YMAX))

    # à compléter...
    
    return im_finale

display(decodage1(codee,masque),2)

Si vous n'avez pas utilisé la puissance de numpy, essayez donc ci-dessous une deuxième version !

In [ ]:
# décodage version 2 (grace à numpy !)

def decodage2(image,masque):
    return # à compléter en une seule ligne !

display(decodage2(codee,masque),3)

Q6. Faire des recherches sur l'historique de cette image et dire pourquoi on a choisi de l'utiliser ici !

Réponse : ...

Q7a. Envisager d'appliquer l'oparateur OR au lieu de XOR et constater que l'on obtient presque l'original. (En python, l'opérateur binaire OR est la barre verticale |

In [ ]:
# décodage avec OR au lieu de XOR

def decodage3(image,masque):
    return # à compléter en une seule ligne !

display(decodage3(codee,masque),4)

Q7b. (facultatif) En déduire un moyen pratique (sans ordianteur, mais en utilisant du calque) pour retrouver l'image originale.

Réponse : ...