-1

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

Cœur
  • 37,241
  • 25
  • 195
  • 267
Nick
  • 393
  • 2
  • 4
  • 10
  • 2
    Your code uses `string` which has not been defined, and calls `GetString()` which has not been declared. Please show the actual code that you are having trouble with. – M.M Apr 04 '14 at 00:34
  • 1
    I think you mean `int keyC - 'a'` in both cases, if you want to support upper-case letters in the keyword then you have to do `islower` etc. on `keyC`, `keyC` is different to `c` – M.M Apr 04 '14 at 00:40
  • i didn't understand your meaning & what variable is not defined? – Nick Apr 04 '14 at 00:48
  • The typedef for `string` is not shown; people are worried about what it is. Similarly, with the function `GetString()`, though the question does mention that it is declared in a header and defined in a library you're using. – Jonathan Leffler Apr 04 '14 at 00:50
  • `string` and `GetString()` are not defined. I guess you are doing a `#include` earlier in the file, which you neglected to show us, which includes a custom header that has those things in it. It's always a good idea to show your entire code, including `#include` lines on here. – M.M Apr 04 '14 at 00:50
  • yes but my code gives result... you don't have to worry about those – Nick Apr 04 '14 at 00:54
  • Don't leave us guessing, and you'll get better answers faster. We try to find all errors, and anything we guess at cannot be used to check for correctness, beside it needing longer. – Deduplicator Apr 04 '14 at 01:28

2 Answers2

2

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.

user3386109
  • 34,287
  • 7
  • 49
  • 68
  • **doesn't advance to the next character if the plain text character is a space character** yes i realized that but why? i am using the check `if(isalpha(c))` – Nick Apr 04 '14 at 01:16
  • true, but the index into the keyword is calculated based on `i`, and `i` increments on every character, space or not. So you need a variable independent of `i` to keep track of where you are in the keyword. – user3386109 Apr 04 '14 at 01:21
  • yes its calculated based on `i` but its calculated if the character is alphabetical so it have to ignore every other kind character like: space right? the other thing with the keyword calculation is understood! thank you... – Nick Apr 04 '14 at 01:27
  • @Nick I updated the answer to demonstrate how the index into the keyword should look. – user3386109 Apr 04 '14 at 01:39
  • i updated my code , i edited my main question with new code check it out,its not working again its like the the isalpha condition doesnt excist and im going to break my monitor!!!! – Nick Apr 04 '14 at 02:14
  • @Nick I have to be brief since I only get 500 chars. There are a few problems with the new variable `j`. After `j` is declared, it must be initialized to 0. The comparison `if ( j > strlen(keyWord) )` should be `if ( j >= strlen(keyWord) )`, because otherwise `j` runs off the end of the keyWord, before being set back to 0. The most important thing, the line `j++;` needs to be at the end of the block of code after the line `if(is alpha( c ))`. That should fix problem 2. – user3386109 Apr 04 '14 at 03:39
  • ok i understood.but why dont you tell me how to make the key shift char only for alphabetical characters? – Nick Apr 04 '14 at 12:15
0

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278