C++ 位运算 : How to decode/decompress char to int, 并显示正确的字符串?

标签 c++ algorithm c++11 decode compression

我正在研究位运算。从我的解码/解压缩算法的第 8 次迭代开始,我的位开始漂移和失控,我需要更有经验/更聪明的人的帮助,这样我的位就不会漂移。我已经在调试器中经历过太多次了,但我仍然无法确定它。我怀疑在某些时候我向左或向右移动了 1 或更多。完整程序位于 Github here .

解码/解压缩的输入是:

unsigned char bytes[25] = { 9,0,207,176,159,163,255,33,58,115,
                              199,255,255,181,223,67,102,69,173,
                              6,35,103,245,160,164 };

引用数组是:

const char symbols[27] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                          'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
                          'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' '};

解码后的“bytes”字符数组的输出是:

'BEAM_ME_UP_SGO_TY____N__INTU_LYGENT__IFE' //Underscores represent space.

使用库:

#include <bitset>
#include <iostream>
#include <queue>
#include <stack>
#include <cassert>
#include <string>
#include <sstream>

算法功能:

/* Function reads one char at a time, and converts chars to int.
 * Resulting integer value then indexes into char array of 27 chars
 * A-Z and 'space', storing results in string stream.
 * */

void bitWiseOpsDemo(unsigned char *bytey, size_t sizeOfArray){ //Input char array and size.
    assert(sizeOfArray>0);
    const int READIBLE_AMOUNT = 5;
    int result;
    stringstream stringOfCharacters;
    string words;
    int numBitsReadible = 0;
    int shift;
    int indexInto;
    short buffer; //will be used to hold bits
    int whileLoopIndex = 0;

    while(whileLoopIndex<sizeOfArray) {
        (buffer |= (bytey[whileLoopIndex]) & 0xFF);
        numBitsReadible += 8;
        result |= (buffer & 0xFFFF); //copy buffer to result.
        while(numBitsReadible>=READIBLE_AMOUNT){//While readible, read
            result |= (buffer & 0xFFFF); //copy buffer to result.
            indexInto = result;
            result <<=5;
            numBitsReadible -= 5; //Reducd the amount of bytes readible by 5.

            //calculate the amount to shift result by
            shift = numBitsReadible;
            result <<= shift;
            indexInto >>=shift;

            (indexInto &= 0x1F); //set all bits to 0, except the five we want in mask
            stringOfCharacters << symbols[indexInto]; //Get symbol and store in streamstring
            if(numBitsReadible==0){
                (result &= 0x0000); //Flush buffer if none readible.
            }
        }
        buffer |= (result &= 0xFF00); // Change 'Y', not 'x': YYYYYYYY xxxxxxxx
        buffer <<= 8; //Make room in buffer for next char
        ++whileLoopIndex;
    }
    words = stringOfCharacters.str();
    cout << words << endl;
}

最佳答案

这行代码没有做你认为它在做的事情,我把它注释掉了......

result |= (buffer & 0xFFFF); //copy buffer to result.

这不是复制。这是工作代码,请注意,我还在下面将位操作中使用的类型更改为无符号。该代码产生

BEAMMEUPSCOTTYNOINTELLIGENTLIFE

我相信这就是你想要得到的。代码如下,注意,我认为SO上的C++大师可以让这个看起来更整洁。

#include <bitset>
#include <iostream>
#include <queue>
#include <stack>
#include <cassert>
#include <string>
#include <sstream>

using namespace std;
const int READIBLE_AMOUNT = 5;

const char symbols[27] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
  'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
  'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' '};

inline void bitWiseOpsDemo(unsigned char *bytey, size_t sizeOfArray){
  assert(sizeOfArray == 25);
  //const int READIBLE_AMOUNT = 5;
  unsigned int result = 0;
  stringstream stringOfCharacters;
  string words;
  int numBitsReadible = 0;
  int shift;
  unsigned int indexInto;
  unsigned short buffer = 0; //will be used to hold bits
  //sizeOfArray = 1; //Only want to loop once right now for testing purposes. Comment out later.
  int whileLoopIndex = 0;
  //int innerLoopIndex = 0;
  while(whileLoopIndex < sizeOfArray) {
    (buffer |= (bytey[whileLoopIndex]) & 0xFF);
    numBitsReadible += 8;
    //result |= (buffer & 0xFFFF); //copy buffer to result.
    result = buffer;
    while(numBitsReadible>=READIBLE_AMOUNT){//While readible, read
      result |= (buffer & 0xFFFF); //copy buffer to result.
      indexInto = result;
      result <<=5;
      //Only want to manipulate the 'result' here
      numBitsReadible -= 5; //Reducd the amount of bytes readible by 5.
      //calculate the amount to shift result by
      shift = numBitsReadible;
      result <<= shift;
      indexInto >>=shift;
      //set all bits to 0, except the five we want in mask
      (indexInto &= 0x1F);

      stringOfCharacters << symbols[indexInto]; //Get symbol and store in streamstring
      if(numBitsReadible==0) {
        (result &= 0x0000); //Flush buffer if none readible.
      }   
    }   
    buffer |= (result &= 0xFF00); // Change 'Y', not 'x': YYYYYYYY xxxxxxxx
    buffer <<= 8; //Make room in buffer for next char
    ++whileLoopIndex;
  }
  words = stringOfCharacters.str();
  cout << words << endl;
}


const size_t SIZE = 25; 

int main() {
  unsigned char bytes[SIZE] = {9, 0, 207, 176, 159, 163, 255, 33, 58, 115, 199, 255, 255, 181, 223, 67, 102, 69, 173, 6, 35, 103, 245, 160, 164};
  bitWiseOpsDemo(bytes, SIZE);
  return 0;
}

关于C++ 位运算 : How to decode/decompress char to int, 并显示正确的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37174562/

相关文章:

c++ - 递归地取消隐藏基类成员

c++ - 重写 OpenCV 的 SIMD 性能膨胀

C++ 隐式转换

c++ - 从文件中读取数据并填充STL vector

php - 是否有任何已知的 php 库可以像 Quora 在其通知提要中那样标记文本更改?如果不是,我应该使用什么算法?

c++ - 如何专门化容器的功能模板?

c++ - 跨多个 gpu 同步原子计数器

algorithm - 你能用最简单的语言向我解释对数复杂度和二分搜索吗

PHP采取所有组合

c++ - 如何在命名空间中引用用户定义的文字运算符?