Pergunta

I'm trying to make a Vigenere cipher code in C and I have done something that is wrong and I can't fix it... How do understand that something goes wrong? Well I have some examples with keyword and result cipher with Vigenere cipher like

  • keyword: bacon
  • text: Meet me at the park at eleven am
  • correct result: Negh zf av huf pcfx bt gzrwep oz
  • my code result with same text and keyword: Tegh ne og tjs qaty bt syfvgb bm

Code:

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

    if( argc != 2  )
    {
        printf("Wrong Argument");
        return 1;
    }
    else
    {
        keyWord = argv[1]; 
        //check if argument is 
        //only alphabetical characters
        for(int i = 0; i < strlen(keyWord); i++)     
        {
            char c = keyWord[i];
            if( !isalpha(c) )
            {
                printf("Your Keyword Must Contain Only alphabetical characters\n");
                return 1;
            }
        }
    }
    //todo
    printf("Enter Plain Text\n");
    string plainText = GetString(); 
    for(int i = 0; i < strlen(plainText); i++) 
    {
        char c = plainText[i];
        int keyWordWrapper;
        char keyC;
        if(isalpha(c))
        {
            keyWordWrapper = i % strlen(keyWord);
            keyC = keyWord[keyWordWrapper];

            if(islower(c))
            {
                int key = keyC - 'a';
                c = (c - 'a'  + key) % 26 + 'a'; 
            }
            if(isupper(c))
            {
                int key = keyC - 'A';
                c = (c - 'A'  + key) % 26 + 'A'; 
            }
        }
        printf("%c",c);
    }
    printf("\n");
    return 0;
}

GetString() is declared in a header and defined in a library that I'm using (it's like scanf).

this is the updated code

int main(int argc, string argv[])

{ string keyWord;

 if( argc != 2  )
{
    printf("Wrong Argument");
    return 1;

}
else
{
    keyWord = argv[1]; 

    //check if argument is 
    //only alphabetical characters
    for(int i = 0; i < strlen(keyWord); i++)     
    {
        char c = keyWord[i];
        if( !isalpha(c) )
        {
            printf("Your Keyword Must Contain Only alphabetical characters\n");
            return 1;
        }  


    }
}

string plainText = GetString(); 

int j;
for(int i = 0; i < strlen(plainText); i++) 
{
    j++;
    char c = plainText[i];
    int keyWordWrapper;
    char keyC;

    if(j > strlen(keyWord))
        j = 0;


    if(isalpha(c))
        {
            keyWordWrapper = i % strlen(keyWord);
            keyC = keyWord[keyWordWrapper];
            int key;
            tolower(c);

            if(islower(keyC))
             key = keyC - 'a';

            if(isupper(keyC))
             key = keyC - 'A';


            c = (c - 'a'  + key) % 26 + 'a'; 




        } 

    printf("%c",c);

}

printf("\n");

return 0; }

Foi útil?

Solução

There are two problems in the code.

First is the treatment of upper case letters in the keyword. Note that in one case, the code subtracts a from keyC, and in the other A is subtracted. But that's based on the case of the plain text character. That subtraction needs to be based on the case of the letter in the keyword.

Second, the code advances to the next character in the keyword for every character in the plain text. The "correct result" doesn't advance to the next character of the keyword if the plain text character is a space character.

Here's an example of what I'm talking about for the second problem

text  Meet me at
keyC  baco nb ac
i     0123456789    i must always increment to the next char in plain text
k     0123 40 12    index into the keyword does not increment on non-alpha

Therefore k cannot be computed directly from i with the line

keyWordWrapper = i % strlen(keyWord);

Instead k needs to be initialized to 0 and then incremented only when the plain text contains an alpha character. The following line will compute the correct index into the keyword.

keyWordWrapper = k % strlen(keyWord);

The only difference is that i is replaced by k and k only increments when the plain text has an alpha character.

Outras dicas

You should convert the key to all lower case (or all upper case) and then use the same expression in both shift blocks:

int key = keyC - 'a';  // Or 'A' if you convert to upper

You should remove the strlen(plainText) from the condition of the for loop; it converts a linear algorithm into a quadratic one.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top