【问题标题】:Vigenere Cipher. Code output维吉尼密码。代码输出
【发布时间】:2016-10-05 15:21:50
【问题描述】:

我一直在研究 cs50 pset2,我认为在研究了几天之后我已经掌握了 vigenere 密码。此代码旨在采用用户给出的字母参数(argv[]),并将其用作密钥,通过其在字母索引中的编号来加密用户(字符串)给出的短语。例如,如果您给出参数 'abc' 和字符串 'cat',那么输出应该是 'cbv'(a 移动 0,b 移动 1,c 移动 2) 参数也应该环绕,这样如果字符串是更长的时间,参数将换行到它的第一个字符并继续直到字符串结束。

这是我的代码:

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


int main(int argc, string argv[])
{


    if(argc != 2)
        {
            printf("Try again\n");
            return 1;
        }
    string k = (argv[1]);

    int klen = strlen(k);


    for(int x = 0; x < klen; x++)
        {
            if(isalpha(k[x]))
                {
                    if(isupper(k[x]))
                        {
                            k[x] = tolower(k[x]);
                        }

                        k[x] -= 'a';
                }
            else
                {
                    printf("Try again\n");
                    return 1;
                }
        }

    string code = GetString();

    int clen = strlen(code);

    for(int a = 0, b = 0; a < clen; a++)
        {
            if(isalpha(code[a]))
                {
                    int key = k[b%klen];
                    if(isupper(code[a]))
                        {
                            printf("%c", (((code[a] - 'A') + key)%26) + 'A');
                            b++;
                        }
                    else
                        {
                            printf("%c", (((code[a] - 'a') + key)%26) + 'a');
                            b++;
                        }
                }
            else
                {
                    printf("%c", code[a]);
                }
        }
    printf("\n");
}

代码似乎适用于键 +1 的长度。 例如, 我输入了一个参数'aaaa'

然后输入一串'bbbbb' 并正确接收“bbbbb”。

但是,如果我输入相同的 'aaaa'

然后输入一个长于键+1 'bbbbbbb'的字符串 我收到'bbbbbNN'

我认为我的操作顺序有问题,但尝试移动括号无济于事。我希望有人能指出我正确的方向,为什么我的密钥没有正确包装。

【问题讨论】:

  • 我无法为您的输入 aaaabbbbbbb 复制此内容,尽管我没有使用任何 string 类型,只是分配 char *k = argv[1];char *code = argv[2]; 其余的内容与您发布的一样。我建议你打印出int klen = strlen(k);的值
  • 我认为你的第三个 printf 应该是printf("%c", (((code[a] - 'a') + (k[b%klen] - 'A'))%26) + 'a');
  • 鲍勃,谢谢。这绝对是问题的一部分。我已经更新了我的代码,但现在我得到的是 bbbbbhh 而不是 bbbbbNN 我似乎仍然无法将密钥包裹在代码周围
  • 该示例没有任何大写字母作为键,所以我没有得到错误的输出。但我还是要问:klen 对应的键 aaaa 的值是多少?
  • klen 的值是 4 与该输入

标签: c cs50 vigenere edx


【解决方案1】:

使用此类代码的最大风险是所有相似的重复子句。一个错误很难跟踪完成。并且在处理代码的同时对密钥进行任何处理都是低效的。

这是一个返工,它在处理代码之前完全处理密钥,并尝试将处理简化为一种情况。看看它是否更适合你:

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

int main(int argc, string argv[])
{

    if (argc != 2)
    {
        fprintf(stderr, "Try again\n");
        return EXIT_FAILURE;
    }

    string key = strdup(argv[1]);

    size_t key_length = strlen(key);

    for (int x = 0; x < key_length; x++)
    {
        if (isalpha(key[x]))
        {
            if (isupper(key[x]))
            {
                key[x] = tolower(key[x]);
            }

            key[x] -= 'a';
        }
        else
        {
            fprintf(stderr, "Try again\n");
            return EXIT_FAILURE;
        }
    }

    string code = GetString();
    int code_length = strlen(code);

    for (int a = 0, b = 0; a < code_length; a++)
    {
        if (isalpha(code[a]))
        {
            int start = isupper(code[a]) ? 'A' : 'a';

            printf("%c", (((code[a] - start) + key[b++ % key_length]) % 26) + start);
        }
        else
        {
            printf("%c", code[a]);
        }
    }

    printf("\n");

    free(key);

    return EXIT_SUCCESS;
}

【讨论】:

  • 感谢您的回复。我对此还很陌生,不明白你写的一些内容,但我会尝试在代码之前获取密钥集,看看会发生什么。
  • 我已经听取了您的建议并在代码循环之外处理了它们的键,并且它有效!它仍然有点混乱,可以简化,但至少它现在可以工作,我可以努力提高它的效率。再次感谢。
猜你喜欢
  • 2016-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 2015-12-01
相关资源
最近更新 更多