简体   繁体   English

C ++使用按位运算从图像中提取字符

[英]C++ Extracting a character from an image using bit-wise operations

this is my first time here asking a questions, so bear with me! 这是我第一次在这里问问题,所以请多多包涵! I have a steganography lab that I am nearly complete with. 我有一个几乎可以完成的隐写术实验室。 I have completed a program that hides a message in the lower bits of an image, but the program to extract the image is where I am stuck. 我已经完成了一个程序,该程序将消息隐藏在图像的较低位,但是提取图像的程序就是我所困的地方。 The image is in a file represented as a 2D matrix, column major order. 图像在一个文件中,以2D矩阵表示,列主要顺序。 So here is the code where I am stuck. 这是我遇到的问题所在的代码。

void image::reveal_message()
{
    int bitcount = 0;
    char c;
    char *msg;
    while(c != '\0' || bitcount < 1128)
    {
        for(int z = 0; z < cols; z++)
        {
            for(int k = 0; k < 8; k++)
            {
                int i = bitcount % rows ;
                int j = bitcount / rows ;
                int b = c & 1;
                if(img[i][j] % 2 != 0 && b == 0)
                {
                    c = c & (~1);
                }
                else if(img[i][j] % 2 == 0 && b == 1)
                {
                    c = c | 1;
                }
                bitcount++;
                c = c << 1;
            }
            reverse_bits(c);
            cout << c << endl;
            //strncat(msg, &c, 1);
        }
    }
    int i = 0;
    for(int i = 0; i < cols; i++)
    {
        if(!isprint(msg[i]))
        {
            cout << "There is no hidden message" << endl;
        }
    }
    cout << "This is the hidden message" << endl;
    cout << msg;
}

The code is able to loop through and grab all the right number for the bits. 该代码能够遍历并获取所有正确的位数。 The bits are based on if the number in the matrix is odd or even. 这些位基于矩阵中的数字是奇数还是偶数。 Where I am having trouble is actually setting the bits of the char to the bits the I extracted from the matrix. 我遇到麻烦的地方实际上是将char的位设置为我从矩阵中提取的位。 I am not the best at bit-wise operations, and we are also not supposed to use any library for this. 我并不是最擅长按位操作,我们也不应该为此使用任何库。 The reverse_bits function works as well, so it seems to be just my shifting and bit-wise operations are messed up.I also commented out the strcat() line because it was producing a lot of errors due to the fact that char c is incorrect. reverse_bits函数也可以正常工作,所以似乎只是我的移位操作和按位操作搞砸了。我也注释掉了strcat()行,因为由于char c错误而导致产生很多错误。 Also the main error I keep receiving is Segmentation Dump. 另外,我一直收到的主要错误是细分转储。

You start with undefined data in your char c . 您可以从char c未定义数据开始。

You read from it here int b = c & 1; 您从这里读取int b = c & 1; .

That is clearly nonsense. 那显然是胡说八道。

            c = c <<1; // shift before, not after
            // if odd clear:
            if(img[i][j] % 2)
            {
                c = c & (~1);
            }
            else // if even set:
            {
                c = c | 1;
            }

the above may not read the data, but at least is not nonesense. 以上可能不会读取数据,但至少不是没有意义。

The bitwise operations look otherwise fine. 按位运算看起来还不错。

char *msg; should be std::string , and use += instead of strncat . 应该是std::string ,并使用+=代替strncat

My understanding from your code is that you embedded your message as 1 bit per pixel, row by row. 根据您的代码,我的理解是您将消息以每像素1位的格式逐行嵌入。 For example, if you have a 3x10 image, with pixels 例如,如果您有一个3x10的图像,其中包含像素

01 02 03 04 05 06 07 08 09 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30

the first character of your message resides in the pixels 01-08, the second from 09 to 16, etc. After your message, you embedded an extra null character, which you can use during extraction to know when to stop. 消息的第一个字符位于像素01-08中,第二个字符位于09到16中,依此类推。消息后,您嵌入了一个额外的空字符,您可以在提取过程中使用它来确定何时停止。 With all that in mind, you're looking for something like this. 考虑到所有这些,您正在寻找类似的东西。

int bitcount = 0;
int i = 0;
int j = 0;

while(bitcount < 1128)
{
    // this will serve as the ordinal value for the extracted char
    int b = 0;
    for(int k = 0; k < 8; k++)
    {
        b = (b << 1) | (img[i][j] & 1);
        j++;
        if(j == cols)
        {
            i++;
            j = 0;
        }
    }
    bitcount += 8;
    // do whatever you want with this, print it, store it somewhere, etc
    c = (char)b;
    if(c == '\0')
    {
        break;
    }
}

Understanding how the bitshifting work. 了解移位的工作方式。 b starts with the value 0, or 00000000 if you would like to visualise it in binary. b以值0开头,如果要以二进制形式可视化,则以00000000开头。 Every time, you shift it to the left by one to make room for the new extracted bit, which you OR. 每次您将其向左移动一个,以便为新提取的位(或)分配空间。 No need to check whether it's 1 or 0, it'll just work. 无需检查它是1还是0,它就可以工作。

So, imagine you've extracted 5 bits so far, b is 00010011 and the least significant bit of the current image pixel is 1. What will happen is this 因此,假设您到目前为止已提取了5位, b为00010011,当前图像像素的最低有效位为1。

b = (b << 1) | 1    // b = 00100110 | 1 = 00100111

And thus you have extracted the 6th bit. 这样就提取了第6位。

Now, let's say you embedded the character "a" (01100001) in the first 8 pixels. 现在,假设您在前8个像素中嵌入了字符“ a”(01100001)。

01 02 03 04 05 06 07 08    \\ pixels
 0  1  1  0  0  0  0  1    \\ least significant bit of each pixel

When you extract the bits with the above, b will equal to 97 and c will give you "a". 当您使用上述方法提取位时, b将等于97,而c将为您提供“ a”。 However, if you embedded your bits in the reverse order, ie, 但是,如果以相反的顺序嵌入位,即

01 02 03 04 05 06 07 08    \\ pixels
 1  0  0  0  0  1  1  0    \\ least significant bit of each pixel

you should change the extracting algorithm to the following so you won't have to reverse the bits later on 您应该将提取算法更改为以下内容,这样以后就不必反转位了

int b = 0;
for(int k = 7; k <= 0; k--)
{
    b = b | ((img[i][j] & 1) << k);
    // etc
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM