2013-03-27 13 views
5

Versuch, grundlegende Steganographie auf einem PPM-Bild zu tun.Steganographie in C

Ich habe den grundlegenden Algorithmus abgeschlossen. Lies die Datei ein, überprüfe, ob die Kopfzeile mit P6 beginnt, erhalte die Bildbreite und -höhe und die Pixeldaten.

Ich brauche insgesamt vier Methoden: ReadPPM, WritePPM, WriteMsg und ReadMsg.

Ich habe die ReadImg und WriteImg-Methoden, aber wo ich feststecke, ist mit meiner WriteMsg-Methode. Dies ist eine einfache Steganographie, die jedes Bit der Zeichenfolge auf das letzte Bit in jedem Byte schreibt. Die ersten 8 Bytes sollen die Größe der versteckten Zeichenfolge enthalten, danach startet jedes Byte danach die verborgene Nachricht.

Meine Idee war, ein riesiges Array zu erstellen, das den Binärcode für die Größe der Zeichenfolge enthält, und dann den Binärcode der Zeichenfolge selbst. Ich versuche nur herauszufinden, wie ich dieses Array nehmen und es zu jedem Byte im Bild hinzufügen würde.

Jede Hilfe wird sehr geschätzt. Hier ist mein aktueller Code:

#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

Die Formatierung Ihres Codes ist meist in Ordnung ... außer für die Funktion, die Sie eigentlich Hilfe wollen! Bitte repariere es. Es ist völlig unlesbar wie es ist. – MatthewD

+0

Sie benötigen zwei Zyklen: einen nach len und einen anderen nach Bits von jedem char, schreiben Sie Daten nur innerhalb des zweiten Zyklus wie @Patashu sagte oder in umgekehrter Reihenfolge ('byte << i & 0x80'). Rollenlänge nicht variabel! –

+0

'len = sizeof (s)' gibt die Größe eines Zeigers zurück. Wenn Sie die Länge der Zeichenfolge möchten, verwenden Sie 'strlen()'. – MatthewD

Antwort

2

Um nur ein einzelnes Bit von einem Byte zu extrahieren, dies zu tun:

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

Dies verschiebt den Bits des Byte nach rechts i-mal, und dann and s es mit 0000 0001 (so dass alle Bits außer dem niedrigsten Null sind, und das niedrigste Bit ist 0 für 0 und 1 für 1).

Sie können ähnlich für 16 Bit kurz, 32 Bit int, 64 Bit lang ... Und auch für die char s einer Zeichenfolge. Sie können sizeof (char) verwenden, um zu sehen, wie viele Bytes in einem Zeichen enthalten sind.

Aber natürlich haben Sie mehr als ein char (oder long oder int oder ...) zu zusätzlichen Bits aus. welches Element extra zu entscheiden, ein bisschen aus:

Wenn Sie das i te Bit wollen und Elemente sind x Bit breit, dann erhalten die i%x Bit von Element [i/x]

Nun, da Sie dieses Bit haben, um es zu platzieren innerhalb eines Bytes (oder int oder char oder ...) zu tun:

steganographybyte = originalbyte & (~ 0x1) + Bit

Was dies bedeutet, ist, nehmen Sie die Nummer ... 0000 0001, invertiere seine Bits, so ist es ... 1111 1110, and es mit dem Original-Byte, so dass alle seine Bits erhalten, außer die niedrigsten, dann fügen Sie einfach Ihr Bit in.