Stéganographie bitmap

Description

Insertion de texte dans une image (cf. Wikipedia -> stéganographie) par parité des composantes de chaque pixel. Les caractères sont convertis en mots binaires qui sont ensuite écris dans les bits de poids faible de chaque composante (RVB), ceci est fait en modifiant la parité des octets.

Source / Exemple :


 #include <stdio.h>  
#include <stdlib.h>  
#include <math.h>  
void Coder(int *binaire, char *adr, int nbBits);  
void Decoder(int *binaire, char *adr, int cle);  
void ToBin(int taille, char *texte, int *texte_binaire); 
void ToASCII(int *binaire, int taille); 
int CarRestants(char *adr); 
#pragma pack(push, 1) typedef struct{ 
    unsigned short type; 
    unsigned long size; 
    unsigned short reserved1; 
    unsigned short reserved2; 
    unsigned long offsetbits; 
} bmpheader; 
#pragma pack(pop) typedef struct{ 
    unsigned long headersize; 
    unsigned long width; 
    unsigned long height; 
    unsigned short planes; 
    unsigned short bitcount; 
    unsigned long compression; 
    unsigned long sizeimage; 
    unsigned long xpelspermeter; 
    unsigned long ypelspermeter; 
    unsigned long colorsused; 
    unsigned long colorsimportant; 
    unsigned char *palette; 
    unsigned char *pixels; 
} bmpinfo; 
int main(int argc, char *argv[]) {
    while(1) {
        int choix, cle, texte_len=-1;
        long caracteresMax;
        char *texte, adr[MAX_PATH]="";
        system("color F9");
        system("cls");
        printf("\t\t**************STEGANOGRAPHIE**************\n\t\t\t\tBy M@gicT0\n\n\n\n\n\t\t\t1 - Coder\n\t\t\t2 - Decoder\n\n\n\n\n\n\t\t\t");
        scanf("%d",&choix);
        getchar();
        if(choix==1){
            system("cls");
            printf("\t\t**************STEGANOGRAPHIE**************\n\t\t\t\tBy M@gicT0\n\n\n\n\n\tImage BMP (sans espaces) : ");
            scanf("%s", adr);
            getchar();
            system("cls");
            caracteresMax=CarRestants(&adr[0]);
            //On récupère le nombre de caractères max
            texte=malloc(caracteresMax*sizeof(char));
            printf("\t\t**************STEGANOGRAPHIE**************\n\t\t\t\tBy M@gicT0\n\n\n\n\n\tTexte (%ld caracteres max): ", caracteresMax);
            fgets(texte, caracteresMax, stdin);
            //On récupère le texte à insérer
            do {
                choix=texte[texte_len];
                //On cherche la longueur de la chaine de texte
                texte_len++;
            }
            while(choix!='\0');
            int *texte_binaire;
            texte_binaire=malloc(texte_len*8*sizeof(int));
            ToBin(texte_len, &texte[0], &texte_binaire[0]);
            //Conversion du texte en binaire
            Coder(&texte_binaire[0], &adr[0], texte_len*8);
            //Insertion du texte dans l'image
            system("cls");
            printf("\t\t**************STEGANOGRAPHIE**************\n\t\t\t\tBy M@gicT0\n\n\n\n\n\t\tTexte ecrit !\n\n\t\tClef :%d\n\n\n\n", texte_len*8);
            getchar();
            free(texte_binaire);
        }     
        else if(choix==2){
            system("cls");
            printf("\t\t**************STEGANOGRAPHIE**************\n\t\t\t\tBy M@gicT0\n\n\n\n\n\tImage BMP (dans le meme dossier) : ");
            scanf("%s", adr);         
            system("cls");         
            printf("\t\t**************STEGANOGRAPHIE**************\n\t\t\t\tBy M@gicT0\n\n\n\n\n\t\tClef : ");
            scanf("%d",&cle);
            int *binaire;
            binaire=malloc(cle*sizeof(int));
            Decoder(&binaire[0], &adr[0], cle);
            //Extraction du texte dans l'image
            system("cls");
            ToASCII(&binaire[0], cle);
            //Conversion du binaire en ASCII
            getchar(); 
            getchar();  
            free(binaire);  
        }     
        else exit(0);     
    }     
    return 0; 
} 
void ToBin(int taille, char *texte, int *texte_binaire) {
    unsigned int hex;
    int i, j, k=8*taille;
    for(j=taille-1;j>=0;j--) //Pour chaque caractère     
    {         
        hex=(int)texte[j]; //On prend son code ASCII         
        for(i=7;i>=0;i--) //Pour chaque bit         
        {             
            texte_binaire[k-1]=hex%2; 
            //On transcode le code ASCII (décimale) en un mot binaire (8 bits)
            hex/=2;
            k--;
        }     
    }     
    return; 
} 
void ToASCII(int *binaire, int taille) {
    int i, j, k, h=0, n, t, temp[8]={0};
    printf("\t\t**************STEGANOGRAPHIE**************\n\t\t\t\tBy M@gicT0\n\n\n\n\n\tTexte : ");
    for(j=0;j<(taille/8);j++) //Pour chaque mot binaire     
    {         
        n=t=0;         
        for(k=0;k<8;k++) temp[k] = binaire[k+(8*j)]; 
        //On stocke mot par mot la chaine binaire pour la traiter ensuite         
        for(i=7;i>=0;i--) //Pour chaque bit         
        {             
            if(temp[i]==1) t+=pow(2,n);
            //Conversion du mot binaire en décimale             
            n++;         
        }         
        printf("%c", t); //Affichage du caractère         
        h++;     
    }     
    printf("\n\n\n\n");     
    return; 
} 
int CarRestants(char *adr) {     
    FILE *img=fopen(adr, "rb");     
    bmpheader header; //structure du header     
    bmpinfo info; //structure de la partie info     
    fread(&header,sizeof(header),1,img); //on lit la partie header     
    fread(&info, sizeof(info), 1, img); //puis la partie info     
    if(header.type != 0x4D42){         
        system("cls");         
        printf("\n\n\n\n\n\n\n\t\t\tCe n'est pas une image Bitmap !\n\n");
        getchar();        
        exit(0);     
    }     
    fclose(img);     
    return (info.width*info.height)*3/8; //On retourne la largeur * la hauteur / 8 (un caractère -> 8bits) 
} 
void Coder(int *binaire, char *adr, int nbBits) {
    FILE *img=NULL, *gen=NULL;     
    img=fopen(adr,"rb"); //Ouverture des fichiers cibles/sources     
    gen=fopen("stegano.bmp","wb+");     
    int i,j, c;     
    if(img != NULL && gen != NULL) //Vérification d'ouverture     
    {         
        for (i=0;i<53;i++) fputc(fgetc(img), gen); //Copie du header (pour un BMP 24 bits)         
        for(i=0;i<nbBits;i++) //Pour chaque bit à insérer         
        {             
            if(binaire[i]==0) //Si c'est un 0             
            {                 
                j=fgetc(img); //On lit l'octet de la composante Rouge      
                if(j%2==1) j--; //Si elle est impaire, on lui soustrait 1     
                fputc(j,gen); //On l'écrit dans le fichier cible       
            }             
            else //Si c'est un 1           
            {                 
                j=fgetc(img); //Idem.      
                if(j%2==0)                 
                {                     
                    if(j!=0) j--; 
                    else j++; 
                }         
                fputc(j,gen);  
            }      
        }       
        while((c=fgetc(img)) != EOF) fputc(c,gen); //On écrit la fin du fichier
    }     
    fclose(img); //On libère les flux en mémoire     
    fclose(gen);     
    return; 
} 
void Decoder(int *binaire, char *adr, int cle) {
    int i;     
    FILE *img=NULL;     
    img=fopen(adr, "rb");     
    if(img != NULL)     
    {         
        fseek(img, 53, SEEK_SET); //On se positionne après le header  
        for(i=0;i<cle;i++) //Pour chaque bit     
        {           
            if(fgetc(img)%2 == 0) binaire[i]=0; //On vérifie sa parité    
            else binaire[i]=1; //pair = 0  |  impaire = 1    
        }    
    }     
fclose(img);   
return; 
}  

Conclusion :


Je ne programme pas souvent, alors soyez indulgents :)

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.