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

CS50替换密码作业:密钥重复字符检测超时问题修复咨询

CS50 Problem Set 2 Substitution密码:密钥重复字符检测超时问题修复

原代码在检测密钥重复字符时无法通过测试,报错信息为:

:( Handles duplicate characters in Key - timed out while waiting for program to exit

问题根源分析

  1. 非法修改只读内存:原代码中string k = argv[1];直接指向命令行参数的只读内存区域,后续执行k[i] = tolower(k[i]);属于未定义行为,可能导致程序崩溃或进入死循环,最终引发超时。
  2. 重复检测逻辑漏洞:仅将k[i]转为小写,但未处理k[j]的大小写,导致大小写不同的重复字符(如'a'和'A')无法被检测到。

修复后的代码

#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, string argv[])
{
    // 检查命令行参数数量是否正确
    if (argc != 2)
    {
        printf("Usage: ./substitution key\n");
        printf("(请仅输入2个命令行参数)\n");
        return 1;
    }

    int key_len = strlen(argv[1]);
    // 创建可修改的密钥副本,避免操作只读内存
    char key[27];
    strcpy(key, argv[1]);

    // 检查密钥长度是否为26位
    if (key_len != 26)
    {
        printf("Usage: ./substitution key\n");
        printf("密钥必须是26个字符\n");
        return 1;
    }

    // 校验密钥是否全为字母,并统一转为小写
    for (int i = 0; i < 26; i++)
    {
        if (!isalpha(key[i]))
        {
            printf("Usage: ./substitution key\n");
            printf("密钥必须全为字母\n");
            return 1;
        }
        key[i] = tolower(key[i]);
    }

    // 检测密钥中的重复字符
    for (int i = 0; i < 26; i++)
    {
        for (int j = i + 1; j < 26; j++)
        {
            if (key[i] == key[j])
            {
                printf("Usage: ./substitution key\n");
                printf("密钥不能包含重复字符\n");
                return 1;
            }
        }
    }

    // 获取明文并执行加密
    string plaintext = get_string("Plaintext: ");
    int text_len = strlen(plaintext);

    printf("ciphertext: ");
    for (int i = 0; i < text_len; i++)
    {
        if (isalpha(plaintext[i]))
        {
            if (isupper(plaintext[i]))
            {
                int idx = plaintext[i] - 'A';
                printf("%c", toupper(key[idx]));
            }
            else
            {
                int idx = plaintext[i] - 'a';
                printf("%c", key[idx]);
            }
        }
        else
        {
            printf("%c", plaintext[i]);
        }
    }
    printf("\n");

    return 0;
}

关键修改点

  • 创建密钥副本:使用char key[27];创建可修改的本地数组存储密钥,避免直接操作只读的命令行参数内存。
  • 统一大小写处理:先将整个密钥转为小写,确保重复检测不受字符大小写影响。
  • 优化重复检测逻辑:基于统一大小写后的密钥进行检测,确保所有重复字符(包括大小写形式不同的)都能被识别。
  • 冗余代码清理:删除了未实际使用的malloc申请的ciphertext变量,简化代码逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:39:18