CS50 维吉尼亚密码 : Can't fix the problem with the spaces in the plaintext

标签 c cs50

我的代码有问题,这应该是 来自哈佛大学 CS50 项目的 Vigenere 密码。我已经遇见了所有的 要求,除非 key 是“baz”并且明文是“hello, world!"。因为有一个逗号和一个空格,所以我的代码接受它,并且 从 z 转移到 a 到 b 等。我希望它忽略空格并 标点符号,以便“b”“a”“z”仅针对字符发生变化。 您应该只需要查看第一个“else if”行,因为那就是
当明文比 key 长时, key 必须
备用。 请帮忙!我已经解决这个问题几个小时了,但我无法弄清楚 解决方案。

https://gyazo.com/3a7b3e692d210262ae15f580b10f296d
https://gyazo.com/0b25bfc010d937840f09ff4294d0dd41
https://gyazo.com/c1b85208ecae1b9ad57d48d5b5af59b5

这是我的代码:

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

int main(int argc, string argv[])
{
    if (argc == 2)
    {
        string key = argv[1];
        int key_length = strlen(key);
        for (int i = 0; i < key_length; i++)
        {
            key[i] = toupper(key[i]);
        }
        for (int k = 0; k < key_length; k++)
        {
            if (key[k] < 'A' || key[k] > 'Z')
            {
                printf("Not a valid key!\n");
                return 1;
            }
        }
        for (int i = 0; i < key_length; i++)
        {
            key[i] = key[i] - 'A';
        }

        string plain = get_string("Plaintext: ");

        int plain_length = strlen(plain);
        if (key_length == plain_length)
        {
            for (int i = 0; i < key_length; i++)
            {
                if (islower(plain[i]))
                {
                    for (int q = 0; q < key[i]; q++)
                    {
                        plain[i]++;
                        if (plain[i] > 'z')
                        {
                            plain[i] = 'a';
                        }
                    }
                }
                if (isupper(plain[i]))
                {
                    for (int q = 0; q < key[i]; q++)
                    {
                        plain[i]++;
                        if (plain[i] > 'Z')
                        {
                            plain[i] = 'A';
                        }
                    }
                }
            }
            printf("ciphertext: %s\n", plain);
        }
        else if (key_length < plain_length)
        {
            float truncate_not = plain_length / key_length;
            int truncate = trunc(truncate_not);
            int mod = strlen(plain) % key_length;
            for (int i = 0; i < truncate; i++)
            {
                for (int k = 0; k < key_length; k++)
                {
                    int pos = k + (i * key_length);
                    if (islower(plain[pos]))
                    {
                        for (int q = 0; q < key[k]; q++)
                        {
                            plain[pos]++;
                            if (plain[pos] > 'z')
                            {
                                plain[pos] = 'a';
                            }
                        }
                        printf("%c\n", plain[pos]);
                    }
                    else if (isupper(plain[pos]))
                    {
                        for (int q = 0; q < key[k]; q++)
                        {
                            plain[pos]++;
                            if (plain[pos] > 'Z')
                            {
                                plain[pos] = 'A';
                            }
                        }
                        printf("%c\n", plain[pos]);
                    }
                    else
                    {
                        printf("error\n");
                    }
                }
            }

            for (int j = 0; j < mod; j++)
            {
                int pos = j + (truncate * key_length);
                if (islower(plain[pos]))
                {
                    for (int q = 0; q < key[j]; q++)
                    {
                        plain[pos]++;
                        if (plain[pos] > 'z')
                        {
                            plain[pos] = 'a';
                        }
                    }
                }
                else if (isupper(plain[pos]))
                {
                    for (int q = 0; q < key[j]; q++)
                    {
                        plain[pos]++;
                        if (plain[pos] > 'Z')
                        {
                            plain[pos] = 'A';
                        }
                    }
                }
                else
                {
                    plain[j] = plain[j];
                }
            }
            printf("ciphertext: %s\n", plain);
        }
        else
        {
            int mod = plain_length % key_length;
            for (int i = 0; i < mod; i++)
            {
                if (islower(plain[i]))
                {
                    for (int q = 0; q < key[i]; q++)
                    {
                        plain[i]++;
                        if (plain[i] > 'z')
                        {
                            plain[i] = 'a';
                        }
                    }
                }
                if (isupper(plain[i]))
                {
                    for (int q = 0; q < key[i]; q++)
                    {
                        plain[i]++;
                        if (plain[i] > 'Z')
                        {
                            plain[i] = 'A';
                        }
                    }
                }
            }
            printf("ciphertext: %s\n", plain);
        }

    }
    else
    {
        printf("Incorrect number of arguments!\n");
        return 1;
    }
}

Actual results: iekmo, wnslc!
Expected results: iekmo, vprke!
As you can see, my code shifted the "baz", when it shouldn't have in the 
space and comma places.

最佳答案

此程序中最重要的问题是将 key_lengthplain_length 联系起来。它们是离散的,必须单独对待;它们以不同的速率“移动”,并且应该使用单独且不同的指数。

首先我建议你rewatch the walkthrough.您可能想使用与 Zamyla 写“panda”示例相同的格式写出(是的,铅笔和纸)“baz”示例。然后编写伪代码。

您可能不得不放弃您编写的大部分代码;一般来说,这个 pset 可以通过一个循环来完成,该循环按索引循环遍历明文,然后在该循​​环内独立管理关键字索引。

关于CS50 维吉尼亚密码 : Can't fix the problem with the spaces in the plaintext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53939390/

相关文章:

CS50 pset4 - 滤镜(不太舒服),棕褐色功能

c - for循环问题

C编程语言,最短路径

使用一行 telnet 语句时,C 套接字读取输出空字符串

c - 反转字符串结构中的每个字符串

c - c 中的内存是如何分配的,为什么两个连续的内存之间的差异总是4?

CS50 现金有效输入退出程序

python - 在 64 位 Windows 10 上构建/安装 PyFMI 包失败

c - 对于数组,为什么 a[5] == 5[a]?

凯撒密码重复字母