7

PPM イメージで基本的なステガノグラフィーを実行しようとしています。

基本的なアルゴリズムが完成しました。ファイルを読み込み、ヘッダーが P6 で始まることを確認し、画像の幅と高さ、およびピクセル データを取得します。

ReadPPM、WritePPM、WriteMsg、ReadMsg の合計 4 つのメソッドが必要です。

ReadImg メソッドと WriteImg メソッドは停止していますが、行き詰まっているのは WriteMsg メソッドです。これは、文字列の各ビットを各バイトの最後のビットに書き込むだけの基本的なステガノグラフィです。最初の 8 バイトには、非表示にする文字列のサイズが含まれていると想定され、その後の各バイトが非表示のメッセージを開始します。

私のアイデアは、文字列のサイズのバイナリ コードを保持する大規模な配列を作成し、次に文字列自体のバイナリ コードを作成することでした。その配列を取得して、画像の各バイトに追加する方法を理解しようとしています。

どんな助けでも大歓迎です。これが私の現在のコードです:

#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++;
              }
         }
    }
}
4

1 に答える 1

2

バイトから 1 ビットだけを抽出するには、次のようにします。

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

これは、バイトのビットを右に i 回シフトし、次にand0000 0001 でシフトします (最下位ビットを除くすべてのビットがゼロになり、最下位ビットが 0 の場合は 0、1 の場合は 1 になります)。

16 ビットの short、32 ビットの int、64 ビットの long についても同様のことができます...そしてchar、文字列の s についても同様です。sizeof(char) を使用して、char に含まれるバイト数を確認できます。

しかし、もちろん、複数の char (または long または int または ...) を余分なビットにする必要があります。どの要素から少し追加するかを決定するには:

番目のビットが必要でi、要素がxビット幅の場合は、i%x要素からビットを取得します[i/x]

このビットを取得したので、それをバイト (または int または char または...) 内に配置するには、次のようにします。

ステガノグラフィバイト = オリジナルバイト&(~0x1) + ビット

これが何を意味するかというと、数字を取得します... 0000 0001、そのビットを反転して... 1111 1110、and元のバイトを使用して、最下位を除いてすべてのビットが保持されるようにし、ビットを追加するだけです。

于 2013-03-27T04:02:46.323 に答える