Vigenere Cipher逻辑错误

时间:2016-09-18 12:11:02

标签: c encryption cs50 vigenere

#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编译

:)加密&#34; a&#34; as&#34; a&#34;使用&#34; a&#34;作为关键字

:(加密&#34;世界,打招呼!&#34;&#34; xoqmd,rby gflkp!&#34;使用&#34; baz&#34;作为关键字

\预期输出,但不是&#34; xoqkj,yfd gfllp!\ n&#34;

:(加密&#34; BaRFoo&#34; as&#34; CaQGon&#34;使用&#34; BaZ&#34;作为关键字

\预期输出,但不是&#34; CaQEun \ n&#34;

:(加密&#34; BARFOO&#34; as&#34; CAQGON&#34;使用&#34; BAZ&#34;作为关键字

\预期输出,但不是&#34; CAQEON \ n&#34;

:(处理缺少argv [1]

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

:(处理argc&gt; 2

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

:(拒绝&#34; Hax0r2&#34;作为关键字

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

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

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题:

您的错误检查不正确。在您已评估android:focusable="true" android:focusableInTouchMode="true" 之后检查if(argc!=2||!apha) - 到那时为时已晚!在访问strlen(argv[1])之前检查argc的有效性,并且不要将参数计数错误和字母键错误加倍,它们是独立的。此外,错误消息应转到argv,而不是stderr

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

stdout

需要保持一致

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;
}

答案 1 :(得分:0)

这是我得到的答案 -

- 最引人注目的错误可能是:

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

应检查相应的字符,因此应检查:

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

- 此外,键增量的增量很重要,只有当它是一个字母表时才会增加。因此需要对isalpha进行检查(因为即使是空间也不希望角色发生变化)。