C ++中的按位移位

时间:2015-03-10 00:10:06

标签: 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);
}

然后通过颠倒上述过程来提取数据:

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;
}

上述隐藏数据功能将每个通道(RGB)转换为二进制。然后,如果它与短语的第n位不匹配(从零开始),它会尝试找到最低有效位并翻转它。然后它将新转换的二进制字符串作为已转换的char分配回指针。

使用bitset库a&#34;最佳实践&#34;技术?我全神贯注于一种更直接,更有效的技术。也许,使用按位maniuplations?

读取和写入PPM图像时没有任何逻辑错误或问题。像素数据被分配给char指针:this-&gt; m_Ptr(上面)。

1 个答案:

答案 0 :(得分:3)

这里有一些更紧凑的代码可以进行位操作。它没有检查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;
}

请注意,此代码从短语的每个字节的lsb到msb进行编码。