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

C++不使用STL实现简单列置换密码的cipher函数加密问题

列置换密码代码问题排查与修正

存在的核心问题

  • 数组填充越界:计算得到的行数是向上取整的结果,当明文字符数不能被列数整除时,最后一行的剩余位置直接访问s[k]会超出字符串范围,属于未定义行为。
  • 加密逻辑完全错误:列置换的核心是按照密钥指定的列顺序读取整列元素,你当前写的arr[n][(arr[n][m] + (key_order[o] - 1))]把字符的ASCII值和密钥相加作为列索引,完全不符合置换逻辑。
  • 密文字符串拼接错误:你用=给cipher赋值,每次都会覆盖之前的内容,最终只会保留最后一个加密字符。
  • 变长数组不符合C++标准:char arr[row][col]是C99特性,标准C++不支持,需要用动态内存分配实现。
  • 密钥长度和列数不匹配:当前key_order是固定长度为5的数组,如果用户输入的col不等于5,会触发数组越界访问。
  • 重复输出密文:cipher函数内部已经打印了密文,main函数中又打印了一次返回值,会重复输出。

修正后的代码

#include <iostream>
#include <string>
using namespace std;

string cipher(string s);
int main()
{
    string s = "";
    cout << "请输入明文:" << endl;
    getline(cin, s);
    cout << cipher(s);
    return 0;
}

string cipher(string s)
{
    int row, col, i, j, m, n, k = 0;
    string cipher = "";
    // 注意这里密钥是1-based的顺序,对应列的读取优先级
    int key_order[] = {3, 5, 4, 2, 1};
    const int key_len = sizeof(key_order)/sizeof(key_order[0]);

    cout << "字符串长度:" << s.length() << endl;
    cout << "请输入列数(必须等于"<< key_len <<",和密钥长度匹配):" << endl;
    cin >> col;
    // 校验列数和密钥长度匹配
    if(col != key_len){
        cout << "列数必须和密钥长度一致!" << endl;
        return "";
    }

    row = s.length() / col;
    if (s.length() % col)
    {
        row += 1;
    }
    cout << "行数:" << row << endl;

    // 动态申请二维数组,符合C++标准
    char** arr = new char*[row];
    for(i = 0; i < row; i++){
        arr[i] = new char[col];
    }

    // 填充二维数组,不足的位置补空格
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            if(k < s.length()){
                arr[i][j] = s[k];
                k++;
            }else{
                arr[i][j] = ' '; // 填充字符可自行调整
            }
        }
    }

    // 加密:按密钥指定的列顺序,逐列读取所有行元素
    for (m = 0; m < col; m++)
    {
        // 密钥是1-based,转成0-based索引
        int target_col = key_order[m] - 1;
        for (n = 0; n < row; n++)
        {
            // 拼接字符而不是覆盖
            cipher += arr[n][target_col];
        }
    }

    // 释放动态申请的内存
    for(i = 0; i < row; i++){
        delete[] arr[i];
    }
    delete[] arr;

    return cipher;
}

逻辑说明

  1. 首先将明文按行优先的顺序填入行*列的二维数组,不足的位置用空格填充
  2. 按照密钥给出的列顺序(key_order中的值为1-based的列号),依次读取每一列的所有行元素,拼接后得到密文
  3. 动态申请的内存使用后及时释放,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:45:07