确定消息是否太长而无法嵌入图像

Determine if a message is too long to embed in an image

我创建了一个程序,通过弄乱文件中每个字节的最后一位,将消息嵌入到 PPM 文件中。我现在遇到的问题是我不知道我是否正在检查消息是否太长或不正确。到目前为止,这是我得到的:

int hide_message(const char *input_file_name, const char *message, const char *output_file_name)
{
    unsigned char * data;
    int n;
    int width;
    int height;
    int max_color;

    //n = 3 * width * height;
    int code = load_ppm_image(input_file_name, &data, &n, &width, &height, &max_color);

    if (code)
    {
        // return the appropriate error message if the image doesn't load correctly
        return code;
    }

    int len_message;
    int count = 0;
    unsigned char letter;

    // get the length of the message to be hidden
    len_message = (int)strlen(message);


    if (len_message > n/3)
    {
        fprintf(stderr, "The message is longer than the image can support\n");
        return 4;
    }

    for(int j = 0; j < len_message; j++)
    {

        letter = message[j];
        int mask = 0x80;

        // loop through each byte
        for(int k = 0; k < 8; k++)
        {
            if((letter & mask) == 0)
            {
                //set right most bit to 0
                data[count] = 0xfe & data[count];
            }
            else
            {
                //set right most bit to 1
                data[count] = 0x01 | data[count];
            }
            // shift the mask
            mask = mask>>1 ;
            count++;
        }
    }
    // create the null character at the end of the message (00000000)
    for(int b = 0; b < 8; b++){
        data[count] = 0xfe & data[count];
        count++;
    }

    // write a new image file with the message hidden in it
     int code2 = write_ppm_image(output_file_name, data, n, width, height, max_color);

    if (code2)
    {
        // return the appropriate error message if the image doesn't load correctly
        return code2;
    }

    return 0;
}

所以我正在检查消息的长度 (len_message) 是否比 n/3 长,这与宽度*高度相同。这看起来正确吗?

您当前正在进行的检查是检查消息的字节 是否多于图像的像素。因为您只使用每像素 1 位来对消息进行编码,所以您需要检查消息的 是否多于消息的像素数。

所以你需要这样做:

if (len_message*8 > n/3)

除了@dbush 关于检查消息中位数的评论之外,您似乎没有考虑图像中所有可用的字节数。正常("raw",P6 格式)PPM 图像每个像素使用三个颜色样本,每个样本 8 位或 16 位。因此,图像至少包含 3 * width * height 字节的颜色数据,可能多达 6 * width * height.

另一方面,隐写术的目的是使隐藏消息的存在难以被发现。为了服务 objective,如果您有一个每个样本 16 位的 PPM,那么您可能希望避免修改样本的更重要的字节。或者,如果您不关心这一点,那么在这种情况下您也可以使用每个样本的整个低位字节。

此外,PPM 文件记录了任何样本的最大可能值,不需要与基础类型的最大值相同。您的技术有可能将实际最大值更改为大于记录的最大值,如果您不更改最大值字段,那么不一致可能是文件已被篡改的提示.

此外,原始 PPM 格式提供了在一个文件中包含多个相同大小的图像的可能性。文件头并没有表示有多少,得看文件大小才能知道。您可以使用文件中每个图像的字节来隐藏您的消息。