位移加密在c++中应使用std::uint8_t逐字节处理,避免char符号陷阱;位移量需模256防未定义行为;加密解密可用同一函数通过正负shift区分;须手动实现字节级循环位移,禁用std::rotate;输出输入必须用二进制模式;该方法无密码学安全性,仅具教学意义。

位移加密在C++里用std::uint8_t逐字节处理最稳妥
直接对char做位移容易踩符号陷阱——比如char在某些平台是signed,左移负值或右移高位补1会破坏原始字节。必须先转成无符号整型再操作。
实操建议:
- 统一用
std::uint8_t读取和写入每个字节,避免平台依赖 - 位移量取模256(即
shift % 256),防止无效大偏移导致未定义行为 - 加密/解密用同一函数,靠
shift正负区分:正为加密,负为解密(或统一用(256 - shift) % 256反向)
示例关键片段:
void shift_cipher(std::vector<:uint8_t>& data, int shift) {
shift = shift % 256;
for (auto& b : data) {
b = static_cast<:uint8_t>((b + shift) & 0xFF);
}
}</:uint8_t></:uint8_t>
std::rotate不能替代字节位移,它移动的是字节位置而非比特
新手常混淆“位移加密”(bitwise shift)和“循环移位”(如ROT13),更有人误用std::rotate——它只是把整个字节数组前后搬动,完全不碰每个字节内部的比特。
真正需要的是按位左/右移,并把溢出比特回填到另一端(即循环位移),但注意:
- C++标准库没有内置字节级循环位移函数,需手动实现:
(b > (8 - n))(n为1~7) - 位移量为0或8时结果恒等于原值,要提前判断避免冗余计算
- 若用
>>对std::uint8_t右移,确保左侧补0(std::uint8_t保证这点;用int则不一定)
这种加密连strings命令都防不住,别用在真实场景
运行strings ./binary | grep -E '[A-Za-z]{4,}'就能从加密后的二进制里捞出可读文本——因为位移加密不改变字符可读性分布,只做线性变换。
典型破绽:
- 明文空格(0x20)加密后变成固定新字节,频率分析立刻暴露
- ASCII字母范围窄(A-Z是0x41–0x5A),位移后仍聚集在某段连续区间,直方图一眼可辨
- 没有密钥派生、无初始化向量(IV)、无扩散机制,无法抵御已知明文攻击
如果真要演示加解密流程,至少加一层XOR混淆:b ^ key_byte ^ shift,但依然不等于安全。
输出文件必须用std::ios::binary打开,否则Windows下会吃掉0x0D
用std::ofstream写加密结果时,若漏掉std::ios::binary标志,在Windows上遇到0x0A会自动补0x0D,导致解密失败且难以排查。
正确写法:
std::ofstream out("cipher.bin", std::ios::binary);
out.write(reinterpret_cast<const char>(data.data()), data.size());</const>
同样,读取时也要用std::ios::binary,否则0x1A(EOF标记)会被截断。
真正难的不是写出能跑的位移代码,而是意识到:只要没用密码学安全的伪随机数生成器、没做填充、没认证加密(AEAD),任何手写的“混淆”都只是给自动脚本多加半秒解析时间。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











