CS50 Pset2 substitution作业加密用例check50不通过求助
CS50 Pset2 substitution替换密码作业问题排查
核心问题排查
你的代码存在3个可直接导致测试不通过的逻辑漏洞:
- 密钥长度校验逻辑完全失效
你直接定义int n = 26,后续判断if (n != 26)抛出长度错误,该判断永远不会触发,没有实际校验输入密钥的长度是否为26位,测试通过属于未定义行为的巧合,正确写法是校验strlen(argv[1]) == 26。 - 重复字符校验存在数组越界漏洞
内层循环中当i和j都等于25时,执行j += 1后j变为26,后续访问argv[1][j]会越界访问非法内存,直接导致程序行为不可预测,这是加密测试项不通过的核心原因。同时你没有将密钥字符统一大小写后再对比重复,若密钥中存在大小写相同的字母(如A和a)不会被判定为重复,不符合题目要求。 - 加密逻辑设计冗余且有越界风险
加密部分的双层循环完全没必要,且处理完非字母字符i自增后,没有加else跳过后续的大小写判断,会直接访问自增后的i对应的明文字符,甚至可能超出明文长度范围,导致输出异常。
修复后可通过所有测试的代码
#include <stdio.h> #include <cs50.h> #include <ctype.h> #include <string.h> int main(int argc, string argv[]) { // 校验参数数量 if (argc != 2) { printf("Usage: ./substitution key\n"); return 1; } // 校验密钥长度 int key_len = strlen(argv[1]); if (key_len != 26) { printf("Key must contain 26 characters.\n"); return 1; } // 校验密钥全为字母 for (int i = 0; i < 26; i++) { if (!isalpha(argv[1][i])) { printf("Usage: ./substitution key\n"); return 1; } } // 校验密钥无重复字符 for (int i = 0; i < 26; i++) { char current = toupper(argv[1][i]); for (int j = i + 1; j < 26; j++) { if (current == toupper(argv[1][j])) { printf("Key must not contain repeated characters.\n"); return 1; } } } // 获取明文 string plaintext = get_string("plaintext: "); int plain_len = strlen(plaintext); // 加密输出 printf("ciphertext: "); for (int i = 0; i < plain_len; i++) { char c = plaintext[i]; if (isupper(c)) { int idx = c - 'A'; printf("%c", toupper(argv[1][idx])); } else if (islower(c)) { int idx = c - 'a'; printf("%c", tolower(argv[1][idx])); } else { printf("%c", c); } } printf("\n"); return 0; }
内容的提问来源于stack exchange,提问作者Ayman Aboukhalifa
相关产品推荐
相关产品推荐

