异或加密仅适用于需快速实现内容不可读的场景(如配置文件),其加解密逻辑相同、无额外开销,但不抗统计分析且密钥泄露即全盘失效,严禁用于敏感数据保护。

为什么用异或(XOR)做文件加密
异或加密不是为了防黑客,而是快速实现“内容不可直接读取”——比如配置文件、日志片段、游戏存档等场景。它的核心优势是:加解密逻辑完全一致,key ^ data 加密,再用同一个 key 异或一次就还原,没有额外开销,也不依赖第三方库。
但必须清楚:它不抗统计分析,不防重放,密钥一旦泄露全部失效。别拿它保护密码或支付数据。
最简可行的 C++ 文件异或加密函数
用 std::ifstream 和 std::ofstream 以二进制模式逐块处理,避免文本换行符干扰和编码问题。
- 密钥必须是
unsigned char类型,否则负值异或会出错 - 推荐用固定长度密钥(如 16 字节),循环使用:第 i 字节用
key[i % key_len] - 务必检查文件打开是否成功,
is_open()比fail()更早发现问题 - 不要用
while (!in.eof())—— 它会在读完最后一字节后仍多执行一次循环
void xor_encrypt_file(const std::string& input_path, const std::string& output_path, const std::vector<unsigned char>& key) {
std::ifstream in(input_path, std::ios::binary);
std::ofstream out(output_path, std::ios::binary);
if (!in.is_open() || !out.is_open()) return;
<pre class="brush:php;toolbar:false;">std::vector<char> buffer(4096);
size_t key_len = key.size();
size_t idx = 0;
while (in.read(buffer.data(), buffer.size())) {
size_t read_bytes = static_cast<size_t>(in.gcount());
for (size_t i = 0; i < read_bytes; ++i) {
buffer[i] ^= key[idx % key_len];
idx++;
}
out.write(buffer.data(), read_bytes);
}
// 处理剩余不足 buffer.size() 的尾部
if (in.gcount() > 0) {
size_t tail_bytes = static_cast<size_t>(in.gcount());
for (size_t i = 0; i < tail_bytes; ++i) {
buffer[i] ^= key[idx % key_len];
idx++;
}
out.write(buffer.data(), tail_bytes);
}}
立即学习“C++免费学习笔记(深入)”;
常见错误:密钥传参和类型踩坑
很多人写 const char* key = "abc" 然后直接异或,结果乱码甚至崩溃——因为字符串字面量是 const char*,而 char 在某些平台默认有符号,-1 ^ 0x80 可能溢出为负,再转成 unsigned char 时行为未定义。
- 始终用
std::vector<unsigned char></unsigned>或std::array<unsigned char n></unsigned>存密钥 - 如果从字符串初始化,显式转换:
std::vector<unsigned char>(s.begin(), s.end())</unsigned> - 避免用
std::string直接存二进制密钥——它可能把\0当结束符截断 - 调试时可打印前几个字节验证:
std::cout
加密后文件还能正常打开吗?
不能。异或会破坏文件头(如 PNG 的 89 50 4E 47),导致系统/软件无法识别格式。这是正常现象,说明加密生效了。解密后必须用原密钥完整还原,哪怕只错一个字节,整个文件都可能损坏(尤其图片、音频)。
所以实际使用中建议:
- 加密前先备份原文件
- 在文件开头或单独元数据中记录密钥长度和校验和(如 CRC32),用于解密时快速判断是否密钥匹配
- 若需“部分可读”,可只加密文件主体,跳过前若干字节(如跳过 ELF 头、ZIP 中心目录)——但这需要你清楚目标文件格式
异或加密真正的难点不在代码,而在密钥分发和生命周期管理——C++ 本身不提供安全存储机制,硬编码密钥等于没加密。











