简体   繁体   English

C ++中的按位移位

[英]Bitwise shifting in C++

Trying to hide data within a PPM Image using C++: 尝试使用C ++隐藏PPM图像中的数据:

void PPMObject::hideData(string phrase)
{
    phrase += '\0';
    size_t size = phrase.size() * 8;
    bitset<8> binary_phrase (phrase.c_str()[0]);

    //We need 8 channels for each letter
    for (size_t index = 0; index < size; index += 3)
    {
        //convert red channel to bits
        bitset<8> r (this->m_Ptr[index]);
        if (r.at(7) != binary_phrase.at(index))
        {
            r.flip(7);
        }

        this->m_Ptr[index] = (char) r.to_ulong();

        //convert blue channel to bits and find LSB
        bitset<8> g (this->m_Ptr[index+1]);
        if (g.at(7) != binary_phrase.at(index+1))
        {
            g.flip(7);
        }

        this->m_Ptr[index+1] = (char) g.to_ulong();

        //convert green channel to bits and find LSB
        bitset<8> b (this->m_Ptr[index+2]);
        if (b.at(7) != binary_phrase.at(index+2))
        {
            b.flip(7);
        }

        this->m_Ptr[index+2] = (char) b.to_ulong();
    }
    //this->m_Ptr[index+1] = (r.to_ulong() & 0xFF);
}

Then extracting the data by reversing the above process: 然后通过逆转上述过程提取数据:

string PPMObject::recoverData()
{
    size_t size = this->width * this->height * 3;
    string message("");
    //We need 8 channels for each letter
    for (size_t index = 0; index < size; index += 3)
    {
        //retreive our hidden data from the LSB in red channel
        bitset<8> r (this->m_Ptr[index]);
        message += r.to_string()[7];

        //retreive our hidden data from the LSB in green channel
        bitset<8> g (this->m_Ptr[index+1]);
        message += g.to_string()[7];

        //retreive our hidden data from the LSB in blue channel
        bitset<8> b (this->m_Ptr[index+2]);
        message += b.to_string()[7];
    }

    return message;
}

The above hide data function converts each channel (RGB) to binary. 上面的隐藏数据功能将每个通道(RGB)转换为二进制。 It then attempts to find the least significant bit and flips it if it does not match the nth bit of the phrase (starting at zero). 然后,它尝试查找最低有效位,如果与短语的第n位不匹配(从零开始),则将其翻转。 It then assigns that new converted binary string back into the pointer as a casted char. 然后,它将新的转换后的二进制字符串作为强制转换字符分配回指针。

Is using the bitset library a "best practice" technique? 使用位集库是“最佳实践”技术吗? I am all ears to a more straightforward, efficient technique. 我非常想念更简单,有效的技术。 Perhaps, using bitwise maniuplations? 也许,使用按位操作?

There are no logic errors or problems whatsoever with reading and writing the PPM Image. 读写PPM映像没有任何逻辑错误或问题。 The pixel data is assigned to a char pointer: this->m_Ptr (above). 像素数据分配给char指针:this-> m_Ptr(上方)。

Here's some more compact code that does bit manipulation. 这是一些执行位操作的更紧凑的代码。 It doesn't bounds check m_Ptr, but neither does your code. 它不会检查m_Ptr,但您的代码也不会。

#include <iostream>
#include <string>

using namespace std;

struct PPMObject
{
  void   hideData(const string &phrase);
  string recoverData(size_t size);

  char m_Ptr[256];
};

void PPMObject::hideData(const string &phrase) 
{
  size_t size = phrase.size();

  for (size_t p_index = 0, i_index = 0; p_index < size; ++p_index)
    for (int i = 0, bits = phrase[p_index]; i < 8; ++i, bits >>= 1, ++i_index)
    {
      m_Ptr[i_index] &= 0xFE;          // set lsb to 0
      m_Ptr[i_index] |= (bits & 0x1);  // set lsb to lsb of bits
    }
}

string PPMObject::recoverData(size_t size)
{
  string ret(size, ' ');

  for (size_t p_index = 0, i_index = 0; p_index < size; ++p_index)
  {
    int i, bits;

    for (i = 0, bits = 0; i < 8; ++i, ++i_index)
      bits |= ((m_Ptr[i_index] & 0x1) << i);

    ret[p_index] = (char) bits;
  }

  return ret;
}

int main()
{
  PPMObject p;

  p.hideData("Hello World!");    
  cout << p.recoverData(12) << endl;

  return 0;
}

Note that this code encodes from lsb to msb of each byte of the phrase. 请注意,此代码从该短语的每个字节的lsb到msb进行编码。

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

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