Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
V. Bénony A. Sedoglavic
Université des Sciences et Technologies de Lille
2003–2004
1 Présentation
La stéganographie (du grec steganos, couvert et graphein, écriture) c’est l’art de cacher un message au
sein d’un autre message de caractère anodin, de sorte que l’existence même du secret en soit dissimulée1 .
Le but de ce projet sera de dissimuler de l’information (sous la forme d’une chaı̂ne de caractères
quelconque) dans une image stockée en BMP. Pour ce faire, nous allons tout d’abord présenter le format
de fichier BMP2 .
1
Tous les champs ne nous concernent pas ; seuls les champs Identifier, DataOffset, Width, Height,
BitsPerPixels, Compression et BitmapDataSize seront réellement nécessaires.
Exercice 1 :
Définissez un type BMP HEADER contenant toutes les informations d’une en-tête BMP. Écrivez ensuite une
fonction permettant de lire l’entête d’un fichier BMP, et dont le prototype sera :
int loadBitmapHeader(FILE *fichier, BMP_HEADER *entete);
On considère donc que le fichier à donc été ouvert à l’extérieur de la fonction, et que le pointeur
retournée par une fonction fopen est donnée en paramètre (pointeur fichier). La fonction aura pour
but de remplir la structure pointée par entete. La fonction retournera 1 si l’opération s’est effectuée
normalement, et 0 sinon.
Exercice 2 :
Écrivez une fonction permettant de vérifier la validité d’un en-tête de fichier BMP. La fonction devra
vérifier :
1. qu’il s’agit bien d’un fichier BMP (en vérifiant que les deux premiers octets soient bien ‘B’ et ‘M’)
2. qu’il s’agit d’un fichier non compressé (le champs Compression doit être égal à 0)
3. que le fichier est bien un fichier en 24 bits (le champs BitPerPixels doit être égal à 24).
4. que la taille des données (BitmapDataSize) est bien égal à Width × Height × 3.
Le prototype de la fonction sera le suivant :
int isBitmapHeaderCorrect(BMP_HEADER *header);
La fonction retournera 1 si tout est correct, et 0 sinon.
2
Exercice 3 :
Écrivez une fonction permettant de calculer un pour tout n connaissant le message m. Le prototype de
la fonction sera :
int getBit(char *m, int n);
Les pixels composant l’image se trouvent, dans le fichier, juste après l’en-tête. Le nombre d’octets
composant ces données est spécifié dans l’en-tête sous le champs BitmapDataSize.
Exercice 4 :
Écrivez une fonction permettant de lire les données d’un fichier BMP. Le header du fichier (qui aura
au préalablement été lu grâce à un appel à la fonction loadBitmapHeader) sera donnée en paramètre à
cette fonction. Elle retournera un pointeur de type unsigned char * qui pointera une zone en mémoire
allouée par cette fonction, et qui contiendra la suite des pixels lus à partir du fichier.
Le prototype de cette fonction sera :
unsigned char * loadBitmapDatas(FILE *fichier, BMP_HEADER *header);
La fonction retournera NULL si elle n’arrive pas à lire les données du fichier BMP. On considère que
la validité du fichier (via la fonction isBitmapHeaderCorrect) aura été vérifié.
Exercice 5 :
Écrivez une fonction permettant de sauvegarder un fichier BMP grâce aux informations d’un header qui
sera donné en paramètre, et d’un pointeur sur une zone en mémoire contenant les pixels de l’image. Le
prototype sera :
4 Fonction de permutation
Afin de ne pas placer le message dans les octets les uns à la suite des autres dans le fichier BMP
résultant, nous allons écrire une fonction capable de construire des fonctions de permutation définie par
un paramètre que l’on appellera la clé du système. Cette fonction de permutation nous permettra de
savoir quels sont les octets de l’image à modifier, et dans quel ordre. Pour représenter f , nous allons
utiliser un tableau de N entiers, où la iième case du tableau contiendra la valeur de f (i).
Une fonction de permutation est une fonction agissant d’un ensemble K = [0 . . . N − 1] d’entiers vers
ce même ensemble K, et dont le but est de définir une bijection.
f : K −→ K
Faire N fois
tirer au hasard deux entiers i et j
les contraindre à l’ensemble [0..N − 1] en calculant
i = i modulo N
j = j modulo N
échanger les cases i et j du tableau représentant la fonction
3
Le problème est qu’il faut être capable de construire à nouveau cette même fonction à tout moment.
Or la notion de hasard ne nous permet pas de connaı̂tre à l’avance la fonction qui va être construite. Pour
contraindre le hasard, nous allons utiliser la fonction C srand(unsigned int seed) afin de modifier
l’état initial du générateur pseudo-aléatoire. Il suffira donc, avant tout appel à la fonction de génération
d’aléa rand d’appeler la fonction srand, paramétrée par la clé du système.
Exercice 6 :
Écrivez une fonction capable de construire une fonction de permutation selon le principe évoqué plus
haut. La fonction retournera un pointeur sur la fonction construite (c’est donc à cette fonction d’allouer
la place en mémoire nécessaire à la représentation de la fonction de permutation)3 . Le prototype sera le
suivant :
Le fait de placer (1 + strlen(m)) × 8 bits dans l’image permet de sauvegarder tous les bits du
message m (soit strlen(m) × 8 bits) plus le zéro qui termine toute chaı̂ne de caractères en C (8 bits
supplémentaires).
Exercice 7 :
Écrivez une fonction capable d’ouvrir un fichier BMP, lire les informations concernant l’en-tête et le
tableau de pixels, cacher un message, et sauvegarder un fichier résultant. Le nom des fichiers à lire et
créer, ainsi que le message et la clé permettant de construire la fonction de permutation seront donnée
en paramètre à la fonction. Le prototype sera :
int hideMessage(char *source, char *dest, char *message, unsigned int key);
source et dest représentent donc les noms des fichiers à respectivement lire, et créer. La fonction
retournera 1 si tout s’est passé correctement, et 0 sinon.
Exercice 8 :
Déterminez l’algorithme capable d’effectuer l’opération inverse, puis écrivez la fonction correspondante
en C4 . Le prototype sera le suivant :
char * retrieveMessage(char *source, unsigned int key);
source sera le nom du fichier BMP à lire.
3 pour les étudiants de mon groupe : la fonction que je vous ai demandé en séance de TP est à modifier (très légèrement)