异或加密利用^运算的可逆性,对字符串每个字符与密钥字节循环异或实现加解密;单字节密钥易被破解,推荐多字节密钥并用unsigned char避免符号扩展问题。

字符串异或加密的原理和基本实现
异或加密本质是利用 ^ 运算的可逆性:对同一字节连续异或同一个密钥,两次操作后恢复原值。C++ 中字符串本质是 std::string(底层为 char 序列),每个 char 可直接参与按位异或,无需额外转换。
最简实现就是遍历每个字符,与密钥字节做 ^:
std::string xor_encrypt(const std::string& s, char key) {
std::string out = s;
for (char& c : out) {
c ^= key;
}
return out;
}
注意:这里用 char key 是单字节密钥;若传入负值(如 -1),会因符号扩展影响结果,建议统一用 unsigned char 类型处理。
多字节密钥循环异或(避免单字节弱密钥)
单字节密钥容易被频率分析破解。实用场景应使用多字节密钥(如密码字符串),并循环应用到每个字符上。
- 密钥长度为 0 时必须提前检查,否则
key[i % key_len]会除零崩溃 - 密钥应转为
std::vector<unsigned char></unsigned>或const unsigned char*,避免char的符号问题导致异或结果不一致 - 推荐用
static_cast<unsigned char></unsigned>强制转换输入字符,防止有符号扩展干扰
示例:
std::string xor_encrypt(const std::string& s, const std::string& key) {
if (key.empty()) throw std::invalid_argument("key cannot be empty");
std::string out = s;
size_t key_len = key.length();
for (size_t i = 0; i (out[i]) ^
static_cast<unsigned char>(key[i % key_len]);
}
return out;
}</unsigned>
解密函数必须与加密完全对称
异或加密/解密逻辑完全相同——只要密钥序列和应用方式一致,调用同一函数即可完成解密。这是它“简单”的核心优势,但也是易错点:
- 加密用了
unsigned char转换,解密也必须用,否则在某些平台(如 MSVC 默认char为有符号)下,负值字符异或结果不一致 - 密钥字符串不能被修改(如误加
.c_str()后又被释放),否则解密时访问野指针 - 如果加密时用了
std::string_view传参,解密也得保持相同生命周期约束
因此,不要写两个不同函数,复用一个更安全:
// 加密和解密都调用这个
std::string xor_cipher(const std::string& data, const std::string& key) { ... }
实际使用时容易忽略的边界问题
看似简单的异或,在真实项目中常因细节翻车:
-
std::string可能含\0字符(比如加密二进制数据),此时不能用c_str()或printf("%s")输出,会提前截断 - 加密后的字符串不再是有效的 UTF-8,不能直接存为文本文件再用记事本打开——可能显示乱码或损坏,建议 Base64 编码后再保存或传输
- 如果密钥来自用户输入,注意去掉首尾空格和 BOM 字节(尤其 Windows 记事本保存的 UTF-8 文件)
- 调试时用
for (auto b : encrypted) printf("%02x ", (unsigned char)b);查看十六进制,比打印字符串更可靠
异或本身不提供完整性保护,也无法抵抗重放或篡改——它只是“混淆”,不是真正意义上的加密。真要用于生产环境,至少得配合 HMAC 或换用 AES。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











