2013-03-27 6 views
5

Provare a fare la steganografia di base su un'immagine PPM.Steganografia in C

Ho completato l'algoritmo di base. Leggere il file, controllare che l'intestazione inizi con P6, ottenere la larghezza e l'altezza dell'immagine e i dati dei pixel.

Ho bisogno di avere un totale di quattro metodi: ReadPPM, WritePPM, WriteMsg e ReadMsg.

Ho i metodi ReadImg e WriteImg in giù, ma dove sono bloccato è con il mio metodo WriteMsg. Questa è la steganografia di base che scrive ogni bit della stringa all'ultimo bit di ogni byte. I primi 8 byte suppongono di contenere la dimensione della stringa che è nascosta, quindi ogni byte dopo che inizia il messaggio nascosto.

La mia idea era quella di creare un enorme array contenente il codice binario per la dimensione della stringa, quindi il codice binario della stringa stessa. Sto solo cercando di capire come prendere quell'array e aggiungerlo a ciascun byte dell'immagine.

Qualsiasi aiuto è molto apprezzato. Qui è il mio codice corrente:

#include<stdio.h> 
#include<stdlib.h> 

typedef struct { 
    unsigned char red,green,blue; 
} PPMPixel; 

typedef struct { 
    int x, y; 
    PPMPixel *data; 
} PPMImage; 

#define CREATOR "RPFELGUEIRAS" 
#define RGB_COMPONENT_COLOR 255 

static PPMImage *readPPM(const char *filename) 
{ 
    char buff[16]; 
    PPMImage *img; 
    FILE *fp; 
    int c, rgb_comp_color; 
    //open PPM file for reading 
    fp = fopen(filename, "rb"); 
    if (!fp) { 
     fprintf(stderr, "Unable to open file '%s'\n", filename); 
     exit(1); 
    } 

    //read image format 
    if (!fgets(buff, sizeof(buff), fp)) { 
     perror(filename); 
     exit(1); 
    } 

    //check the image format 
    if (buff[0] != 'P' || buff[1] != '6') { 
     fprintf(stderr, "Invalid image format (must be 'P6')\n"); 
     exit(1); 
    } 

    //alloc memory form image 
    img = (PPMImage *)malloc(sizeof(PPMImage)); 
    if (!img) { 
     fprintf(stderr, "Unable to allocate memory\n"); 
     exit(1); 
    } 

    //check for comments 
    c = getc(fp); 
    while (c == '#') { 
    while (getc(fp) != '\n') ; 
     c = getc(fp); 
    } 

    ungetc(c, fp); 
    //read image size information 
    if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) { 
     fprintf(stderr, "Invalid image size (error loading '%s')\n", filename); 
     exit(1); 
    } 

    //read rgb component 
    if (fscanf(fp, "%d", &rgb_comp_color) != 1) { 
     fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename); 
     exit(1); 
    } 

    //check rgb component depth 
    if (rgb_comp_color!= RGB_COMPONENT_COLOR) { 
     fprintf(stderr, "'%s' does not have 8-bits components\n", filename); 
     exit(1); 
    } 

    while (fgetc(fp) != '\n') ; 
    //memory allocation for pixel data 
    img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel)); 

    if (!img) { 
     fprintf(stderr, "Unable to allocate memory\n"); 
     exit(1); 
    } 

    //read pixel data from file 
    if (fread(img->data, 3 * img->x, img->y, fp) != img->y) { 
     fprintf(stderr, "Error loading image '%s'\n", filename); 
     exit(1); 
    } 

    fclose(fp); 
    return img; 
} 

void writePPM(const char *filename, PPMImage *img) 
{ 
    FILE *fp; 
    //open file for output 
    fp = fopen(filename, "wb"); 
    if (!fp) { 
     fprintf(stderr, "Unable to open file '%s'\n", filename); 
     exit(1); 
    } 

    //write the header file 
    //image format 
    fprintf(fp, "P6\n"); 

    //comments 
    fprintf(fp, "# Created by %s\n",CREATOR); 

    //image size 
    fprintf(fp, "%d %d\n",img->x,img->y); 

    // rgb component depth 
    fprintf(fp, "%d\n",RGB_COMPONENT_COLOR); 

    // pixel data 
    fwrite(img->data, 3 * img->x, img->y, fp); 
    fclose(fp); 
} 

void writeMsg(PPMImage *img, char *s) 
{ 

    int i; 
    int len; 
    len = sizeof(s); 

    if (img) 
    { 
     j = 0; 
     for (i=0; i < img->x * img->y; i++) 
     { 
       while(j < 8) 
       { 
        if(len & 0x80) 
        { 
         img->data[i].red= img->data[i].red | 0x01; 
        } 
        else 
        { 
         img->data[i].red= img->data[i].red & 0xFE; 
        } 

        len=len << 1; 
        j++; 

        if (len & 0x80) 
        { 
         img->data[i].green= img->data[i].green | 0x01; 
        } 
        else 
        { 
         img->data[i].green= img->data[i].green & 0xFE; 
        } 


        len = len << 1; 
        j++; 

        if (len & 0x80) 
        { 
         img->data[i].blue= img->data[i].blue | 0x01; 
        } 
        else 
        { 
         img->data[i].blue= img->data[i].blue & 0xFE; 
        } 
        j++; 
       } 
     } 
    } 
} 
+0

La formattazione del tuo codice è per lo più soddisfacente ... tranne per la funzione con cui effettivamente vuoi aiuto! Per favore aggiustalo. È completamente illeggibile così com'è. – MatthewD

+0

Sono necessari due cicli: uno di len e un altro di bit di ogni carattere, i dati di scrittura solo all'interno di un secondo ciclo come @Patashu detto o in ordine inverso ('byte << i & 0x80'). Non arrotolare la variabile di lunghezza! –

+0

'len = sizeof (s)' restituirà la dimensione di un puntatore. Se vuoi la lunghezza della stringa, usa 'strlen()'. – MatthewD

risposta

2

Per estrarre solo un singolo bit da un byte, fare questo:

bit(i) = byte >> i & 0x1

Questo sposta i bit del byte a destra i tempi, e poi and s con 0000 0001 (tale che tutti i bit tranne il più basso vengono azzerati e il bit più basso è 0 per 0 e 1 per 1).

Si può fare simile per 16 bit brevi, 32 bit int, 64 bit lunghi ... E anche per il char s di una stringa. Puoi usare sizeof (char) per vedere quanti byte ci sono in un char.

Ma ovviamente avrete più di un carattere (o long o int o ...) da bit extra. Per decidere quale elemento in più un po 'da:

Se si desidera che il i esimo bit e gli elementi sono x bit di larghezza, quindi ottenere il bit i%x da elemento [i/x]

Ora che avete questo bit, per posizionarlo all'interno di un byte (o iNT o char o ...), fare:

steganographybyte = originalbyte & (~ 0x1) + po

Che cosa questo significa è, si prende il numero di ... 0000 0001, invertire i suoi bit in modo che sia ... 1111 1110, and con il byte originale in modo che tutti i suoi bit vengano conservati TRANNE il più basso, quindi aggiungi il tuo bit.