C++ C+中的位移位+;

C++ C+中的位移位+;,c++,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 &

试图使用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);
}
void PPMObject::hideData(字符串短语)
{
短语+='\0';
size\u t size=phrase.size()*8;
位集二进制_短语(短语.c_str()[0]);
//我们每封信需要8个频道
对于(大小索引=0;索引<大小;索引+=3)
{
//将红色通道转换为位
位集r(此->m_Ptr[索引]);
if(r.at(7)!=二进制短语at(索引))
{
r、 翻转(7);
}
这->m_Ptr[index]=(char)r.to_ulong();
//将蓝色通道转换为位并查找LSB
位集g(这个->m_Ptr[index+1]);
if(g.at(7)!=二进制短语at(索引+1))
{
g、 翻转(7);
}
这->m_Ptr[index+1]=(char)g.to_ulong();
//将绿色通道转换为位并查找LSB
位集b(这个->m_Ptr[index+2]);
如果(b.at(7)!=二进制(索引+2))
{
b、 翻转(7);
}
这->m_Ptr[index+2]=(char)b.to_ulong();
}
//这->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;
}
string PPMObject::recoverData()
{
尺寸=此->宽度*此->高度*3;
字符串消息(“”);
//我们每封信需要8个频道
对于(大小索引=0;索引<大小;索引+=3)
{
//从红色通道中的LSB检索隐藏数据
位集r(此->m_Ptr[索引]);
message+=r.to_string()[7];
//在绿色通道中从LSB检索隐藏数据
位集g(这个->m_Ptr[index+1]);
message+=g.to_string()[7];
//在蓝色通道中从LSB检索隐藏数据
位集b(这个->m_Ptr[index+2]);
message+=b.to_string()[7];
}
返回消息;
}
上述隐藏数据功能将每个通道(RGB)转换为二进制。然后,它尝试查找最低有效位,如果它与短语的第n位(从零开始)不匹配,则将其翻转。然后,它将新转换的二进制字符串作为转换字符重新分配给指针

使用位集库是一种“最佳实践”技术吗?我全神贯注于一种更直接、更有效的技术。也许,使用按位手动上载


读取和写入PPM图像时不存在任何逻辑错误或问题。像素数据被分配给一个字符指针:this->m_Ptr(上图)。

这里有一些更紧凑的代码,可以进行位操作。它不会检查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;
}
#包括
#包括
使用名称空间std;
结构PPMObject
{
void hideData(常量字符串和短语);
字符串恢复数据(大小\u t大小);
字符m_Ptr[256];
};
void PPMObject::hideData(常量字符串和短语)
{
size_t size=短语.size();
对于(大小p_指数=0,i_指数=0;p_指数=1,++i_index)
{
m_Ptr[i_index]&=0xFE;//将lsb设置为0
m_Ptr[i_index]|=(位&0x1);//将lsb设置为位的lsb
}
}
字符串PPMObject::recoverData(大小)
{
字符串ret(大小为“”);
对于(大小p_指数=0,i_指数=0;p_指数位|=((m|Ptr[i|u index]&0x1)对我来说,直接位操作会更清晰。比如:this->m|Ptr[index]=(char)(r.To|ulong()&0xFF);但这是LSB的正确十六进制代码吗?下面添加了解码逻辑。我的编码位逻辑稍微有点不正确。