You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
}

验证步骤

  1. 输入包含接近126的字符(比如'~',ASCII 126),手动设置difference为1,此时var2 = 127,超过126,分支应触发输出。
  2. 检查charQ和intQ是否正确存入对应的数据。
  3. 查看加密后的文件和控制台输出,确认逻辑符合预期。

内容的提问来源于stack exchange,提问作者LordVader

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:50:01