C++自定义密码加密器if分支无输出问题求助
C++自定义密码加密器if分支无输出问题排查与解决
问题背景
我用C++实现自定义密码加密器,加密逻辑如下:
- 用
rand()生成两个随机数:difference(0-19)、secondDifference(20-39) - 遍历输入字符串的每个可打印字符(ASCII 33-126),将字符加上
difference得到var2 - 若
var2的ASCII值大于126:将原字符减去secondDifference存入字符队列,同时记录字符索引到整数队列 - 若
var2不超过126:直接将var2存入栈实现逆序存储
但代码中if (var2 > 126)的分支始终无输出,调整代码位置也无法解决问题,完整加密函数代码如下:
void encrypt(string data) { srand(time(0)); fstream myFile("difference.dat", ios::binary); fstream myfile("difference2.dat", ios::binary); int difference = rand() % 20; int secondDifference = 20 + (rand() % 20); cout << difference << " " << secondDifference <<endl; myFile.write(reinterpret_cast<char*>(&difference), sizeof(difference)); myfile.write(reinterpret_cast<char*>(&secondDifference), sizeof(secondDifference)); for (int i = 0; i < data.length(); i++) { char var1 = data[i]; if (var1 > 32 && var1 < 127) { char var2 = var1 + difference; if (var2 > 126) { char var3 = var1 - secondDifference; cout << var3; charQ.push(var3); intQ.push(i); } stack1.push(var2); } } fstream binaryFile("encrypted.dat", ios::binary); while (!stack1.isEmpty()) { char c = stack1.top(); binaryFile.write(reinterpret_cast<char*>(&c), sizeof(c)); stack1.pop(); } binaryFile.close(); cout << "Encrypted password: "; ifstream encryptedFile("encrypted.dat", ios::binary); char encryptedChar; while (encryptedFile.read(reinterpret_cast<char*>(&encryptedChar), sizeof(encryptedChar))) { cout << encryptedChar; } encryptedFile.close(); cout << endl; myFile.close(); }
核心问题分析
问题出在有符号char的溢出行为:
在绝大多数编译器中,char是默认有符号的类型,取值范围为-128 ~ 127。当var1 + difference的结果超过127时,会触发有符号整数溢出,导致var2变成负数(比如126+2=128,溢出后变为-128)。此时var2 > 126的判断永远为假,分支自然不会执行。
举个具体例子:
var1为ASCII 120(字符'x'),difference为10,计算得120+10=130- 130超出有符号
char的最大值127,溢出后结果为130 - 256 = -126 - 此时
-126 > 126不成立,分支逻辑被跳过
另外原代码存在逻辑错误:无论是否触发分支,都会执行stack1.push(var2),这不符合加密逻辑——触发分支时应该存入处理后的var3,而非溢出后的var2。
解决方法
1. 改用无符号类型计算
将var2的类型改为unsigned char,同时把var1转为无符号类型后再做加法,避免溢出导致的负数问题,同时修正栈的存入逻辑:
// 修改原循环内的计算逻辑 char var1 = data[i]; if (var1 > 32 && var1 < 127) { // 将var1转为无符号类型后计算,避免溢出 unsigned char var2 = static_cast<unsigned char>(var1) + difference; if (var2 > 126) { char var3 = var1 - secondDifference; cout << var3; charQ.push(var3); intQ.push(i); // 触发分支时存入处理后的var3 stack1.push(var3); } else { // 未溢出时存入原var2 stack1.push(var2); } }
2. 优化随机数生成
原代码中srand(time(0))放在encrypt函数内,若短时间内多次调用该函数,time(0)返回的秒数相同,会导致随机数重复。建议将srand移到程序的入口函数(比如main)中,只调用一次。
3. 补充边界处理
当var1 - secondDifference的结果小于32(ASCII可打印字符下限)时,会生成不可打印字符,可能影响后续解密。可以添加循环偏移逻辑确保结果为可打印字符:
char var3 = var1 - secondDifference; while (var3 < 32) { var3 += 95; // 95是可打印字符的数量(126-32+1) }
验证步骤
- 输入包含接近126的字符(比如'~',ASCII 126),手动设置
difference为1,此时var2 = 127,超过126,分支应触发输出。 - 检查
charQ和intQ是否正确存入对应的数据。 - 查看加密后的文件和控制台输出,确认逻辑符合预期。
内容的提问来源于stack exchange,提问作者LordVader
相关产品推荐
相关产品推荐

