【问题标题】:Vigenere Cipher logic errorVigenere 密码逻辑错误
【发布时间】:2016-09-18 12:11:01
【问题描述】:
#include<stdio.h>
#include<cs50.h>
#include<ctype.h>
#include<string.h>
int main(int argc, string argv[]){
int k,j,i=0,ch,pos;
bool apha=true;
string in = GetString();
int num = strlen(in);
    for(int z=0;z<strlen(argv[1]);z++){
        if(!isalpha(argv[1][z])){
        apha=false;
        }
    }
    if(argc!=2||!apha){
    printf("Dude we only accept alphabets...");
    return 1;
    } 
string key = argv[1];
int keylength = strlen(key);
   for (i=0,j=0;i<num;i++,j++){
        if(isupper(key[i])){
            k=key[j%keylength]-'A';
        }
        if(islower(key[i])){
        k=key[j%keylength]-'a';
        }
            if(isupper(in[i])){
                pos=in[i]-'A';
                ch = ((pos + k)%26) + 'A';
                printf("%c",ch);
            }
            if(islower(in[i])){
                pos=in[i]-'a';
                ch = ((pos + k)%26) + 'a';
                printf("%c",ch);
            }
            if(isspace(in[i])){
                printf(" ");
            }
            if(ispunct(in[i])){
                printf("%c",in[i]);
            }
    }
printf("\n");
}

输出条件检查: :) vigenere.c 存在

:) vigenere.c 编译

:) 使用“a”作为关键字将“a”加密为“a”

:( 使用“baz”作为关键字将“world, say hello!”加密为“xoqmd, rby gflkp!”

\ 预期输出,但不是“xoqkj, yfd gfllp!\n”

:(使用“BaZ”作为关键字将“BaRFoo”加密为“CaQGon”

\预期的输出,但不是“CaQEun\n”

:(使用“BAZ”作为关键字将“BARFOO”加密为“CAQGON”

\ 预期输出,但不是“CAQEON\n”

:( 处理缺少 argv[1]

\预期的输出,而不是输入提示

:( 处理 argc > 2

\预期的输出,而不是输入提示

:(拒绝“Hax0r2”作为关键字

\预期的输出,而不是输入提示

我的代码有什么问题?我仔细检查了逻辑,错误似乎在于密钥的包装方式,尽管我找不到任何错误。我哪里出错了?

【问题讨论】:

  • ".. \ 预期的输出,而不是输入提示.." 是否因为没有要求输入的代码而皱眉?
  • 好吧,也许……但这是一个简单的错误(或多或少),这是让我害怕的逻辑错误。
  • SO 主要用于提出明确的问题,调试/修复代码对其他人几乎没有用处。请向您所在的机构寻求帮助。
  • 您在检查密钥时使用了错误的索引:isupper(key[i]),在使用之前最好“预处理”密钥(预先计算 k 值)。
  • 我知道我不应该在 SO...如果有人看到这种错误,则问题出在密钥增量器(此处为 j)的增量中。

标签: c encryption cs50 vigenere


【解决方案1】:

你的代码有几个问题:

您的错误检查不正确。在你已经评估了strlen(argv[1]) 之后检查if(argc!=2||!apha)——到那时已经太晚了!在访问argv 之前检查argc 的有效性,并且不要将参数计数错误和字母键错误加倍,它们是独立的。此外,错误消息应发送至stderr,而不是stdout

您完全错误地处理了键索引。正如@Bob__ 所指出的,此代码中的索引:

if(isupper(key[i])){
    k=key[j%keylength]-'A';
}

需要保持一致

if (isupper(key[j % keylength])) {
    k = key[j % keylength] - 'A';
}

而且,你没有正确增加j,你让它跟踪i

for (i=0,j=0;i<num;i++,j++){

相反,i 应针对输入字符串中的每个字符递增,j 应针对输入字符串中的每个可加密字母递增。

修改您的代码以修复上述错误和一般样式问题,我们得到如下内容:

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

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

    if (argc != 2) {
        fprintf(stderr, "Please supply an encryption key.\n");
        return 1;
    }

    string key = argv[1];
    int key_length = strlen(key);
    bool is_alpha = true;

    for (int z = 0; z < key_length; z++) {
        if (!isalpha(key[z])) {
            is_alpha = false;
        }
    }

    if (!is_alpha) {
        fprintf(stderr, "Sorry, we only accept alphabetic keys.\n");
        return 1;
    }

    string in = GetString();
    size_t length = strlen(in);

    for (int i = 0, j = 0; i < length; i++) {

        if (isalpha(in[i])) {

            int ch, k = key[j++ % key_length];

            if (isupper(k)) {
                k -= 'A';
            } else {
                k -= 'a';
            }

            if (isupper(in[i])) {
                int pos = in[i] - 'A';
                ch = ((pos + k) % 26) + 'A';
            } else {
                int pos = in[i] - 'a';
                ch = ((pos + k) % 26) + 'a';
            }

            printf("%c", ch);
        } else if (isspace(in[i])) {
            printf(" ");
        } else if (ispunct(in[i])) {
            printf("%c", in[i]);
        }
    }

    printf("\n");

    return 0;
}

使用模拟

> ./a.out baz
world, say hello!
xoqmd, rby gflkp!
>

【讨论】:

    【解决方案2】:

    这是我得到的答案-

    -最显着的错误可能是:

       if(isupper(key[i])){
       k=key[j%keylength]-'A';
       }
    

    它应该检查相应的字符,所以应该检查:

       if (isupper(key[j % keylength])) {
       k = key[j % keylength] - 'A';
       }
    

    -此外,键增量的增量很重要,要做到这一点,只有当它是字母表时才增量。因此需要对其进行 isalpha 检查(因为您不希望字符更改为空格)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多