位提取和隐写术

3

我正在尝试使用隐写术。我试图从一张图片中提取一个文本文件。我能够读取文件并获取位,但是在提取这些位时遇到了问题。

int getbits( pixel p) {
    return p & 0x03;   
}

char extract ( pixel* image ) {
    static int postion;
    postion = 0;

    postion = *image;

    postion++;

    char curChar;
    curChar = '\0';
    for(int i = 0; i<4; ++i) {
        curChar = curChar << 2;
        curChar = curChar | getbits(postion);
    }
    return curChar;
}

Pixel是一个无符号字符。我有一个循环调用extract()fputc(3)的返回值。我感觉从这些位上得到了垃圾。这导致我返回了巨大的(1.5GB)txt文件。

void decode( PgmType* pgm, char output[80] )
{
FILE*outstream;
int i, length;

outstream = fopen(output, "w");

if(!outstream)
{
    fatal("Could not open");
}
for(i=0; i < 16; ++i)
{
    length = length << 2;
    length = length | getbits(*pgm->image);
}
if ((length* 4) < (pgm->width * pgm->height))
{
    fatal("File Too Big");
}
for (i = 0 ;i<length; ++i)
{
    fputc(extract(pgm->image), outstream);

}
fclose(outstream);

}

5
是“隐写术”还是“密码术”? - Emre Yazici
2
展示调用extract的循环 - 因为您应该演示正确地遍历图像。 - borrible
@borrible 我已经包含了循环。 - Joe Tyman
2个回答

2
你实际上只读取了图像中的第一个像素 - [编辑] 因为当你试图使用静态变量来计数时,正如Oli所指出的那样,你立即就会覆盖它。
相反,使用位置跟踪计数,但在另一个变量中保存数据:
extract()应该看起来像这样:
char extract ( pixel* image )
{
   static int postion = 0;

   pixel data = image[position];

   postion++;

   // use 'data' for processing
}

这是一个转移注意力的策略; OP 立即用 *image 覆盖了 position... - Oliver Charlesworth
@Joe:我猜你调用了比图像数组中像素数量更多的提取次数。你能看到哪次迭代出现了错误吗? - DaveR
@Dave 这不是第一个问题,它正在创建一个文件并且超出了数组的范围。 - Joe Tyman
@Dave 我也不得不在循环中放置 position++。 - Joe Tyman

2

戴夫·里格比的优秀诊断是正确的,但将position作为参数传递(并且在此处不进行递增)会导致更易理解和更灵活的例程:

char extract ( pixel* image, int position ) {
    char curChar = '\0';
    for(int i = 0; i<4; ++i) {
        curChar = curChar << 2;
        curChar = curChar | getbits(postion);
    }
    return curChar;
}

char *build_string(pixel *image) {
    int i;
    char *ret = malloc(SECRET_SIZE);
    for (i=0; i<SECRET_SIZE; i++) {
        ret[i]=extract(image, i);
    }
    ret[i] = '\0';
    return ret;
}

当你意识到改变一行中的所有像素会很明显,而你更愿意使用斐波那契值处的像素时,这个更改就很容易实现:

char *build_string_via_fib(pixel *image) {
    int i;
    char *ret = malloc(SECRET_SIZE);

    for (i=0; i<SECRET_SIZE; i++) {
        ret[i]=extract(image, fib(i));
    }
    ret[i]='\0';
    return ret;
}

你也可以将斐波那契计算嵌入到你的extract()例程中,但是将函数分解成最小、最有用的部分,可以使代码更易读、易测试,并且能够获得最佳的未来代码复用机会。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接