c++如何实现字符串的按位异或_c++基础加密解密演示【入门】

2次阅读

直接对std::String异或出错因operator[]返回有符号char,负值异或易出错,且’’被误参与运算致解密截断;应遍历data()、用size()控长、char转unsigned char再异或。

c++如何实现字符串的按位异或_c++基础加密解密演示【入门】

为什么直接对 std::string 做异或会出错

因为 std::string 是容器,不是原始字节数组;它的 operator[] 返回的是 char(有符号),而异或运算在负值上容易产生意外结果。更关键的是,字符串末尾的 '' 会被当成有效字符参与运算,解密时可能提前截断。

  • 实际操作应遍历 data()c_str() 指向的底层内存,长度用 size() 控制,避开 '' 干扰
  • 务必把 char 强转为 unsigned char 再异或,否则 -1 ^ 0xFF 这类计算会因符号扩展出错
  • 加密/解密必须用同一密钥、同一字节序列顺序,否则无法还原

std::string 异或加解密的最小可行写法

下面这段代码能真正双向工作,不依赖额外库,且兼容中文、emoji 等 UTF-8 字节流(注意:它按字节异或,不按字符):

std::string xor_cipher(const std::string& input, unsigned char key) {     std::string out = input;     for (size_t i = 0; i < input.size(); ++i) {         out[i] = static_cast(input[i]) ^ key;     }     return out; }

调用示例:

std::string plain = "hello 世界"; std::string cipher = xor_cipher(plain, 0x55); std::string restored = xor_cipher(cipher, 0x55); // 恢复原值
  • 密钥用 unsigned char 类型最安全,避免隐式转换问题
  • 不能用 std::string::at()——它带边界检查,性能差且没必要
  • 如果密钥是字符串(如 "key123"),需改用循环异或(即多字节密钥),否则这里只支持单字节

多字节密钥异或(Vigenère 风格)怎么写才不出错

常见错误是用 key[i % key_len] 但忘了把密钥字符也转成 unsigned char,导致某次异或结果为负,再存进 string 就变成截断或乱码。

立即学习C++免费学习笔记(深入)”;

  • 密钥字符串必须先转为 std::vector,避免 char 符号问题
  • 索引用 i % key.size(),不要手写 key_len 变量——容易不同步
  • UTF-8 下一个汉字占 3 字节,异或后仍是合法 UTF-8 的概率极低,所以这种加密不保证可读性,仅用于演示或轻量混淆

简写示例:

std::string xor_vigenere(const std::string& s, const std::string& key) {     if (key.empty()) return s;     std::vector k(key.begin(), key.end());     std::string out = s;     for (size_t i = 0; i < s.size(); ++i) {         out[i] = static_cast(s[i]) ^ k[i % k.size()];     }     return out; }

调试时最常见的三个崩溃点

这些不是语法错误,但上线前一跑就崩:

  • std::string 被 move 后又访问——比如传入临时对象 xor_cipher(get_data(), 0x42),内部若用了引用或指针缓存就危险
  • 密钥为 0x00:异或后所有字节不变,看似“没加密”,但若后续逻辑依赖加密结果非空,可能触发空指针或越界
  • 跨平台读写二进制字符串:windows 下用 std::ofstream 默认文本模式,会把 n 换成 rn,导致字节错位;必须加 std::ios::binary

异或本身很简单,难的是字节解释一致、内存生命周期可控、编码边界清晰——这几个地方松动一点,加密就变成随机变换。

text=ZqhQzanResources