Partie B2 · exercices 33 à 35

Bonus : cacher un message dans une image

La stéganographie : ne pas chiffrer, mais dissimuler

Chiffrer un message le rend illisible, mais cela se voit. La stéganographie fait autre chose : elle cache l'existence même du message, par exemple dans une photo. Cette partie, facultative, réutilise ce que tu as vu dans le thème Photographie numérique.

CoursLe dernier bit

Dans une image RVB, chaque couleur d'un pixel est un nombre de 0 à 255, c'est-à-dire un octet. Changer ce nombre de 1 ne se voit pas à l'œil : 200 et 201 donnent deux rouges quasi identiques. On peut donc utiliser le dernier bit de chaque nombre pour stocker un bit du message.

Le dernier bit, en Python

  • 200 % 2 donne 0 (nombre pair) ; 201 % 2 donne 1 (nombre impair).
  • Le dernier bit d'un nombre est donc nombre % 2.

Dans ce bonus, on cache le message dans le canal rouge des pixels, en lisant l'image ligne par ligne. Le message est écrit en code ASCII, 8 bits par caractère. Le fichier image_secrete.png (dans l'archive à télécharger : Cryptage.zip) contient un message caché. On utilise un fichier PNG : un fichier JPEG modifierait les valeurs des pixels.

ExercicesExercices

EX 33Je découvre 🌶️prise en main

Exercice 33 — Invisible ?

  1. Quel est le dernier bit de 200, de 201, de 37, de 88 ? (utilise % 2)
  2. Si le message est « A » (code ASCII 65, soit 01000001 en binaire), quels bits doit-on écrire dans 8 pixels successifs ?
  3. Pourquoi la modification d'un bit sur un pixel est-elle invisible ?
Indice

65 en binaire : 64 + 1, soit 01000001.

📝 réponses dans ton compte rendu, exercice 33

EX 34Je programme 🌶️🌶️application

Exercice 34 — Lire le message caché

Enregistre image_secrete.png dans le même dossier que ton programme, puis complète les deux lignes du programme (l'extraction du dernier bit, puis la conversion en caractère).

lire.py
from PIL import Image

img = Image.open("image_secrete.png").convert("RGB")
largeur, hauteur = img.size

bits = ""
for y in range(hauteur):
    for x in range(largeur):
        r, v, b = img.getpixel((x, y))
        bits = bits + str(r % ...)                 # à compléter : le dernier bit de r

message = ""
for i in range(0, len(bits) - 7, 8):
    octet = bits[i:i + 8]
    code = int(octet, 2)
    if code == 0:
        break
    message = message + chr(...)                   # à compléter

print(message)
  1. Complète, exécute : quel est le message caché ?
  2. À quoi sert int(octet, 2) ?
  3. Que signifie if code == 0: break ?
Indice

int("01000001", 2) donne 65, et chr(65) donne "A".

💾 NOM_Prenom_ex34.py

EX 35Je synthétise 🌶️🌶️🌶️plusieurs étapes

Exercice 35 — Combien peut-on cacher ?

  1. Une image fait 800 × 600 pixels. Combien de bits peut-on cacher avec un bit par pixel ?
  2. Combien de caractères cela fait-il ?
  3. Pourquoi la stéganographie ne remplace-t-elle pas le chiffrement ? Que faire pour combiner les deux ?
Indice

Un caractère = 8 bits.

📝 réponses dans ton compte rendu, exercice 35