Insertion d'un texte dans un fichier bitmap en c

Description

C'est un petit prog de stegano, pour qu'il marche, il faut mettre un .bmp renommer test.bmp dans le meme repertoire que l'application. La partie cryptage du texte avant insertion dans le bitmap est courte, en effet, je fait un complement a 1 sur chaque char avant de l'inserer.

Source / Exemple :


Voila le main.c

#include <stdio.h>
#include <stdlib.h>
#include "stegano.h"
  
/* Le code ASCII de l'application est iso-latin-1 ou iso-8859-1
Dans cette norme, chaque caractere est codé sur 8 bits.
Chaque pixel d'un bitmap (en couleurs réelles, soit celle en 24 bits) est
composé de trois couleur codé chacune sur 8 bits.
Un fichier bitmap comprend en premier un en-tête de 54 octers avant l'image
proprement dite.
La technique est simple : j'ouvre le fichier dans un flux, je lit caractere par
caractere, ce qui me donne la valeur (de 0 a 255) de la couleur qui compose une
des trois couleur de l'image.
Imaginons que je veuille inserer la lettre "a" (0x61) donc 01100001 en binaire.
Le premier pixel est composé en RGB de 231, 12, 125.
Le deuxieme pixel est composé en RGB de 132, 156, 62.
Le troisieme pixel est composé en RGB de 128, 42, 23.
Je prend la premiere couleur du premier pixel : 231 donc 0xE7 ou 11100111b
Je change le dernier caractere de la suite binaire de la couleur et je le 
change par le premier bit de la lettre a inserer soit 0. La sequence binaire
de cette couleur devient donc 11100110b soit 0xE6 ou 230.
Je réétere l'opération avec les deux couleurs suivantes, en incluant a chaque
fois le bit suivant de ma lettre. Le premier pixel est donc constituer de :
130, 13, 125. On s'aperçoit que la derniere couleur n'est pas modifié : Ceci est
dû au fait que que le bit à changer de la même valeur que le troisième bit de la
lettre a insérer.
Ici, jai besoin de 8 couleurs pour coder la lettre "a", soit deux pixels et les 
deux premières couleurs du pixel suivant.Un bitmap fait en moyenne 600000 octet.
Soit 600000/2 = 300000 couleurs = 100000 pixels.
Avec ceci, je peux coder un texte de 37500 caractères, ce qui déja pas mal...
ATTENTION, le nombre de bit pour coder une couleur peut varier, mais elle est
indiquer dans l'en-tête du bitmap.

  • /
int main(){ EnTeteFichier Entete; int choix, i; while (choix!=0){ system("cls"); printf("\n****************************************\n"); printf("************** MENU *****************\n"); printf("*****************************************\n"); printf("* 1 ) Inserer du texte *\n"); printf("* 2 ) Desinserer du texte *\n"); printf("* 3 ) Voir les informations sur l image *\n"); printf("* 0 ) Quitter *\n"); printf("*****************************************\n"); scanf("%d", &choix); switch (choix){ case 1 : system("cls"); InsereTexte(); system("PAUSE"); break; case 2 : system("cls"); RetireTexte(); system("PAUSE"); break; case 3 : system("cls"); Entete = InfoImage(); i = Entete.TailleFichier-54; printf("Le fichier fait %i octets\n", Entete.TailleFichier); printf("L image mesure %i x %i pixels\n", Entete.LargeurImage, Entete.HauteurImage); printf("L image fait %i octets, un texte de %i caractere peut etre inserer dedans\n", i, (i / 8)); system("PAUSE"); break; case 0 : printf("Fin du programme\n"); break; default : printf("erreur de saisie"); } } system("PAUSE"); return 0; } Voila le stegano.h #include <stdio.h> #include <stdlib.h> //Structure d'entete de bmp typedef struct{ char Signature[2]; unsigned int TailleFichier; unsigned int Reserve; unsigned int Offset; unsigned int TailleEntete; unsigned int LargeurImage; unsigned int HauteurImage; unsigned short int NombrePlan; unsigned short int Profondeur; unsigned int MethodeCompression; unsigned int TailleImage; unsigned int ResolutionHorizontale; unsigned int ResolutionVerticale; unsigned int NbreCouleurPalette; unsigned int NbreCouleurImportante; }EnTeteFichier; void InsereTexte(); void RetireTexte(); EnTeteFichier InfoImage(); Voila le stegano.c #include <stdio.h> #include <stdlib.h> #include "stegano.h" void InsereTexte(){ FILE * test; FILE * dest; int a; char b; int i; int nbcaractere=0; int bitfaible; char * texte; printf("Avant d inserer du texte, merci de verifier que vous avez bien"); printf(" placer un bitmap couleur \"vrai\" dans le meme repertoire que"); printf(" cette application. Merci de renommer votre bitmap en test.bmp\n"); fflush(stdin); printf("Veuillez taper le texte a inserer dans l'image : "); gets(texte); nbcaractere=strlen(texte); //ouverture des fichiers bmp test=fopen("test.bmp","rb"); dest=fopen("dest.bmp","w+b"); if (test!=NULL){ system("cls"); // recopie de l'entete for(i=0;i<54;i++){ fputc(fgetc(test),dest); } i=0; //traitement stegano while((a=fgetc(test))!=EOF){ if (i<nbcaractere){ b=texte[i]; b=crypte(b); //Traitement du premier bit du caractere texte[i] //prend le bit de poid faible de a bitfaible=a & 1; if ((b & 128) == 128){ //Premier bit=0 if (bitfaible==0){ a=a+1; } }else{ //Premier bit=1 if (bitfaible==1){ a=a-1; } } fputc(a,dest); a=fgetc(test); //Traitement du deuxieme bit du caractere texte[i] //prend le bit de poid faible de a bitfaible=a & 1; if ((b & 64)==64){ //Premier bit=0 if (bitfaible==0){ a=a+1; } }else{ //Premier bit=1 if (bitfaible==1){ a=a-1; } } fputc(a,dest); a=fgetc(test); //Traitement du troisieme bit du caractere texte[i] //prend le bit de poid faible de a bitfaible=a & 1; if ((b & 32)==32){ //Premier bit=0 if (bitfaible==0){ a=a+1; } }else{ //Premier bit=1 if (bitfaible==1){ a=a-1; } } fputc(a,dest); a=fgetc(test); //Traitement du quatrieme bit du caractere texte[i] //prend le bit de poid faible de a bitfaible=a & 1; if ((b & 16)==16){ //Premier bit=0 if (bitfaible==0){ a=a+1; } }else{ //Premier bit=1 if (bitfaible==1){ a=a-1; } } fputc(a,dest); a=fgetc(test); //Traitement du cinquieme bit du caractere texte[i] //prend le bit de poid faible de a bitfaible=a & 1; if ((b & 8)==8){ //Premier bit=0 if (bitfaible==0){ a=a+1; } }else{ //Premier bit=1 if (bitfaible==1){ a=a-1; } } fputc(a,dest); a=fgetc(test); //Traitement du sixieme bit du caractere texte[i] //prend le bit de poid faible de a bitfaible=a & 1; if ((b & 4)==4){ //Premier bit=0 if (bitfaible==0){ a=a+1; } }else{ //Premier bit=1 if (bitfaible==1){ a=a-1; } } fputc(a,dest); a=fgetc(test); //Traitement du septieme bit du caractere texte[i] //prend le bit de poid faible de a bitfaible=a & 1; if ((b & 2)==2){ //Premier bit=0 if (bitfaible==0){ a=a+1; } }else{ //Premier bit=1 if (bitfaible==1){ a=a-1; } } fputc(a,dest); a=fgetc(test); //Traitement du dernier bit du caractere texte[i] //prend le bit de poid faible de a bitfaible=a & 1; if ((b & 1)==1){ //Premier bit=0 if (bitfaible==0){ a=a+1; } }else{ //Premier bit=1 if (bitfaible==1){ a=a-1; } } i++; fputc(a,dest); }else{ fputc(a,dest); } } printf("\"%s\" a bien ete inserer dans l'image. Vous trouverez le resultat dans le bitmap dest.bmp\n",texte); }else{ printf("Une erreur est survenue lors du fichier bitmap test.bmp\n"); printf("Ceci peut venir du fait que vous ne l avez pas placer"); printf(" dans le meme repertoire que l'application.\n"); } fclose(test); fclose(dest); } void RetireTexte(){ FILE * image; int i; char a; char b=1; int bitfaible; int fin=0; fflush(stdin); printf("Avant de sortir le texte cache dans votre bitmap, merci de verifier ces points : \n"); printf(" - le bitmap est dans le meme repertoire que cette application\n"); printf(" - le bitmap est renomme en dest.bmp\n"); printf("\nMerci. Tout est ok ? (0 pou oui)"); scanf("%i", &i); if (i==0){ system("cls"); //Sortie du texte image=fopen("dest.bmp","rb"); for(i=0;i<54;i++){ fgetc(image); } i=0; printf("Voici le texte cache dans le bitmap dest.bmp :\n"); while((a=fgetc(image))!=EOF){ if ((b!=0)&&(fin==0)){ b=0; bitfaible=a&0x01; b=b+(bitfaible*128); a=fgetc(image); bitfaible=a&0x01; b=b+(bitfaible*64); a=fgetc(image); bitfaible=a&0x01; b=b+(bitfaible*32); a=fgetc(image); bitfaible=a&0x01; b=b+(bitfaible*16); a=fgetc(image); bitfaible=a&0x01; b=b+(bitfaible*8); a=fgetc(image); bitfaible=a&0x01; b=b+(bitfaible*4); a=fgetc(image); bitfaible=a&0x01; b=b+(bitfaible*2); a=fgetc(image); bitfaible=a&0x01; b=b+(bitfaible*1); if(b!=0){ b=decrypte(b); } printf("%c",b); }else{ fin=1; } i++; } printf("\n"); fclose(image); }else{ printf("Sortie de la fonction. "); } } EnTeteFichier InfoImage(){ FILE * image; EnTeteFichier Entete; image=fopen("dest.bmp","rb"); fread(&(Entete.Signature), 1, 2, image); fread(&(Entete.TailleFichier), 4, 1, image); fread(&(Entete.Reserve), 4, 1, image); fread(&(Entete.Offset), 4, 1, image); fread(&(Entete.TailleEntete), 4, 1, image); fread(&(Entete.LargeurImage), 4, 1, image); fread(&(Entete.HauteurImage), 4, 1, image); fread(&(Entete.NombrePlan), 2, 1, image); fread(&(Entete.Profondeur), 2, 1, image); fread(&(Entete.MethodeCompression), 4, 1, image); fread(&(Entete.TailleImage), 4, 1, image); fread(&(Entete.ResolutionHorizontale), 4, 1, image); fread(&(Entete.ResolutionVerticale), 4, 1, image); fread(&(Entete.NbreCouleurPalette), 4, 1, image); fread(&(Entete.NbreCouleurImportante), 4, 1, image); fclose(image); return Entete; } Voila le Cryptage.h #include <stdio.h> #include <stdlib.h> int crypte(int lettre); int decrypte(int lettre); Voila le Cryptage.c #include <stdio.h> #include <stdlib.h> #include "Cryptage.h" int crypte(int lettre){ return ~lettre; } int decrypte(int lettre){ return ~lettre; }

Conclusion :


Ca a été codé avec dev-c++.
Bon, ce prog est simple, il sert simplement a montrer que la manipulation des bits n'est vraiment pas compliqué. Si vous avez des remarques, ou des améliorations a faire, n'hésitez pas a me les faire remarquer

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.