xor加密需以binary模式用read()/write()逐块处理字节,密钥循环使用,避免文本模式换行符转换和operator>>截断;大文件应分块(如64kb)而非全载入内存。

用 std::ifstream 和 std::ofstream 逐字节读写实现 XOR 加密
异或加密在 C++ 中本质就是对每个字节执行 ^ 运算,密钥可以是单字节(如 0x55)或多字节(需循环使用)。关键不是“能不能”,而是“怎么避免破坏二进制数据”。必须以 std::ios::binary 模式打开文件,否则 Windows 下遇到 0x0A/0x0D 会被自动转换,导致加解密不一致。
常见错误现象:std::ifstream 默认文本模式读取后文件变短、内容错乱、解密后无法打开图片/PDF;或者用 operator>> 读字符串,遇到 \0 提前截断。
- 始终用
std::ios::binary打开输入和输出流 - 用
read()/write()处理原始字节,不要用>>或getline() - 密钥长度为 1 时最简单;多字节密钥需用
key[i % key_len]循环索引 - 加密和解密逻辑完全相同:对同一文件执行两次 XOR 同一密钥,即可还原
处理大文件时避免内存爆炸:分块读取 std::vector<char></char>
把整个文件读进内存再处理,看似简洁,但遇到几百 MB 的视频或数据库文件就直接 OOM。更稳妥的做法是固定缓冲区大小(如 64KB),循环读—异或—写。这样内存占用恒定,且 I/O 效率不差。
示例片段(省略错误检查):
std::ifstream fin("input.bin", std::ios::binary);
std::ofstream fout("output.bin", std::ios::binary);
std::vector<char> buf(65536);
const char key[] = {0x12, 0x34, 0x56};
const size_t key_len = sizeof(key);
while (fin.read(buf.data(), buf.size())) {
size_t n = fin.gcount();
for (size_t i = 0; i 0) {
size_t n = fin.gcount();
for (size_t i = 0; i
<h3>密钥管理:别硬编码在源码里,也别用 <code>std::string</code> 存二进制密钥</h3>
<p>把密钥写死在代码里(比如 <code>const char key = 0xAA</code>)等于没加密;而用 <code>std::string</code> 接收用户输入的十六进制密钥串(如 <code>"1a2b3c"</code>)时,必须手动解析成字节,不能直接拿 <code>string.data()</code> 去 XOR —— 否则你 XOR 的是 ASCII 字符 <code>'1'</code>、<code>'a'</code>,而不是字节 <code>0x1A</code>。</p>
<ul>
<li>命令行传入 hex 字符串时,用 <code>std::stoi(s.substr(i,2), nullptr, 16)</code> 转字节</li>
<li>从文件读密钥要同样用 <code>binary</code> 模式,防止换行符污染</li>
<li>若密钥来自用户密码,至少做一次 <code>std::hash<:string>{}(pwd)</:string></code> 得到固定长度种子,再扩展成密钥(虽仍不安全,但比明文密码直用强)</li>
</ul>
<h3>异或加密的局限性:它根本防不住有心人</h3>
<p>XOR 是对称、无扩散、无混淆的运算。只要攻击者知道或猜出哪怕一小段明文(比如 PNG 文件头是 <code>\x89\x50\x4E\x47\x0D\x0A\x1A\x0A</code>),就能立刻反推出对应位置的密钥字节;若密钥短,还能统计重复模式。它只适合临时隐藏、防手误打开、或作为更大加密流程中的一个环节。</p>
<p>真正需要保密时,请用 <code>libsodium</code> 或 <code>OpenSSL</code> 的 AEAD 模式(如 <code>crypto_aead_chacha20poly1305_encrypt</code>),而不是自己拼 XOR。C++ 标准库不提供加密原语,强行“自制”只会制造虚假安全感。</p>
<p>最容易被忽略的一点:XOR 加密后的文件,其文件头已面目全非——用 <code>file</code> 命令看会显示 “data”,连是不是文本都判断不了。调试时别盯着输出文件双击打开,先用 <code>xxd -l 16 output.bin</code> 看前 16 字节是否符合预期。</p></char>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











