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; }
逻辑说明
- 首先将明文按行优先的顺序填入
行*列的二维数组,不足的位置用空格填充 - 按照密钥给出的列顺序(
key_order中的值为1-based的列号),依次读取每一列的所有行元素,拼接后得到密文 - 动态申请的内存使用后及时释放,避免内存泄漏
内容的提问来源于stack exchange,提问作者Maroof
相关产品推荐
相关产品推荐

