Bit-Shift 一个字符串来解码保存文件 C++

Bit-Shift a string to decode save file C++

我有点想解码我的保存文件。我想到了这个。但是从保存文件中将字符移回原位似乎无法正常工作。只有数字似乎恢复正确,但所有其他字符似乎都变成了奇怪的符号。如您所见,我将 savecontent << 1 向左位移,在加载时,我将传入行 >> 1 向右位移。但它没有像我预期的那样工作。位移在字符串上不能正常工作吗?

void erGuiManager::SaveToFile(string filename) {
    ofstream ifs;
    ifs.open(filename, ios::binary);

    if (ifs.is_open())
    {
        string savecontent = "";
        for (int i = 0; i < guiItems.size(); i++) {
            if (dynamic_cast<erGuiBasicNode*>(guiItems[i])) {
                savecontent.append( dynamic_cast<erGuiBasicNode*>(guiItems[i])->save(true));
            }
        }
        for (int i = 0; i < savecontent.length(); i++) {
            savecontent[i] = savecontent[i] << 1;
        }
        ifs.write(savecontent.c_str(), strlen(savecontent.c_str()));
        ifs.close();
    }
    else {
        cout << "Error: Unable to open file " << filename;
    }
}

void erGuiManager::LoadFromFile(string filename) {
    string line;
    string out;
    ifstream myfile(filename);
    if (myfile.is_open())
    {
        while (getline(myfile, line))
        {
            for (int i = 0; i < line.length(); i++) {
                line[i] = line[i] >> 1;
            }
            out.append(PasteNodeFromString(line,true));
        }
        ConnectBezierLines(out);
        myfile.close();
    }
}

运算符 >> 执行 arithmetic shift,这意味着所有 >=64 的值的最高位都为 1,这不是您想要的。在 ASCII 中,数字用 48 到 57 之间的值表示,字母从 65 开始,所以这就是字母不起作用的原因。

一个简单的解决方案是将最高位显式设置为零:

line[i] = (line[i] >> 1) & 0x7f;

这仍然意味着您只能使用字符集的下半部分,即值 <127。更好的解决方案是轮换 shift:

line[i] = (line[i] << 1) | (line[i] >> 7)&0x01;

编码和

line[i] = (line[i] >> 1)&0x7f |(line[i]<<7);

积分提升有一个微妙的问题(因为 char 没有 operator<<,所以它被提升为 int)和符号扩展。

考虑:

int main() {
    char a = 127;
    printf("%hhd\n", a);

    char b = a << 1;
    printf("%hhd\n", b);

    char c = b >> 1;
    printf("%hhd\n", c);
}

及其输出:

127
-2
-1

如您所见,原始值无法恢复。

修复是在 unsigned space 中操作,这样就不会发生符号扩展:

int main() {
    char a = 127;
    printf("%hhd\n", a);

    char b = static_cast<unsigned char>(a) << 1;
    printf("%hhd\n", b);

    char c = static_cast<unsigned char>(b) >> 1;
    printf("%hhd\n", c);
}

正确输出:

127
-2
127

在这种特殊情况下,只需要 static_cast<unsigned char>(b) >> 1 即可解决此问题,但是,在执行移位时,应该了解整数提升和符号扩展。

没有投射:

char(254) >> 1 === int(-2) >> 1 === int(-1) === char(-1)

演员阵容:

unsigned char(254) >> 1 === int(254) >> 1 === int(127) === char(127)