CS50x 2019 pset2:Vigenère 不能完全工作

CS50x 2019 pset2: Vigenère does not fully work

我目前正在研究 CS50x 2019 的 pset2,特别是 Vigenère。 CS50 成绩簿在上传到 GitHub 后显示我已完成 93%。

我已经尝试了一些您可以在网上找到的其他代码片段,但它们似乎没有用。

这是我创建密文的程序部分:

    string k = argv[1];
    // Get the plaintext and print out the ciphertext
    string s = get_string("plaintext: ");
    printf("ciphertext: ");

    // Iterate through plaintext letter by letter
    for (int i = 0, n = strlen(s) ; i < n; i++)
    {
        int key = tolower(k[i % strlen(k)]) - 'a';

        // Check if the letter is lowercase, uppercase or neither and print out the rotated character
        if (islower(s[i]))
        {
            printf("%c", (((s[i] - 'a') + key) % 26) + 'a');
        }
        else if (isupper(s[i]))
        {
            printf("%c", (((s[i] - 'A') + key) % 26) + 'A');
        }
        else
        {
            printf("%c", s[i]);
        }
    }

    printf("\n");
    return 0;

文档中有一些示例,您可以使用您的代码进行测试。

以下示例不适用于我的代码:

$ ./vigenere bacon
plaintext:  Meet me at the park at eleven am
ciphertext: Negh zf av huf pcfx bt gzrwep oz

我的输出是:

$ ./vigenere bacon
plaintext: Meet me at the park at eleven am
ciphertext: Negh ne og tjs qaty bt syfvgb bm

如您所见,前 4 个字符是正确的,但其余的不正确。

这个int key = tolower(k[i % strlen(k)]) - 'a';是个问题。

来自规范:

Remember also that every time you encipher a character, you need to move to the next letter of k, the keyword (and wrap around to the beginning of the keyword if you exhaust all of its characters). But if you don’t encipher a character (e.g., a space or a punctuation mark), don’t advance to the next character of k!

底线是:因为 plaintextkey 运行 在不同的 "rates" 你不能使用相同的索引(在这种情况下 i)对彼此而言。程序应该一次抓取 plaintext 个字符,就像这里所做的那样。但它需要一种单独的方式来控制 key 中的字符,因此您可以 1) 跳过 spaces/punctuation 和 2) 环绕。 key 索引的另一个变量是解决它的一种方法。代码中可能还有其他问题,但这是一个根本性的缺陷。