Vigenere 密码逻辑错误

Vigenere Cipher logic error

#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" 作为关键字

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

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

你的代码有几个问题:

你的错误检查不正确。在评估 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!
>

这是我得到的答案-

-最明显的错误可能是:

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

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

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

-此外,键增量的增量很重要,只有当它是字母时才增量。因此需要对此进行 isalpha 检查(因为即使 space,您也不希望字符发生变化)。