Search code examples
ccs50vigenere

Vigenere Cipher Black Hawk Down


I cannot figure out why this thing doesn't scramble correctly. I read some other posts on this cipher and as far as I can tell I'm using the exact same algorithm as they are...

The areas commented out are tests I tried to make sure everything was passing through correctly. I believe it all goes through correctly then fails in the algorithm.

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

string get_message(void);
string scramble(string key, string message);

int main(int argc, string argv[])
{
    if(argc == 2)
    {
        string key;
        string message;

        key = argv[1]; 
        //printf("KEY: %s<<",key); 
        message = get_message();
        scramble(key, message);
    }
    else
    {
        printf("Please enter 2 arguments.\n");
        return 1;
    }
}

string get_message(void)
{   
    string message = "";
    do
    {
        message = GetString();
    }
    while(strlen(message) < 1);
    return message;
}

string scramble(string key,string message)
{       
    for(int i = 0, len = strlen(message), key_len = strlen(key); i < len; i++)
    {   
        int letter = message[i];
        //int Tkey = atoi(key[i % key_len]); 
        //printf("KEY: %d<<\n",Tkey);

        if(islower(letter))
        {
            //printf("KEY(%d)",(key[i % key_len]-97));
            letter = (((letter - 97) + (key[i % key_len])) % 26 + 97);
            //printf("(%d)",(letter - 97) + (key[i % key_len])%26);
            printf("%c",letter);
        }       
        else if(isupper(letter))
        {
            //printf("(%d)", key[i]);
            //printf("(%c)",letter); WE HAVE CORRECT LETTER
            letter = (((letter - 65) + (key[i % key_len])) % 26 + 65);
            printf("%c",letter);
        }
    }
    printf("\n");
    return 0;
}

Solution

  • I think your calculation is wrong:

    You currently have

    encryptedLetter = (letter - firstLetterOffset) + key[position % keyLength] % 26 + firstLetterOffset
    

    by check the C operator precedence table we notice that % is evaluated before - or +, meaning that your code actually mean :

    encryptedLetter = (letter - firstLetterOffset) + ( key[position % keyLength] % 26 ) + firstLetterOffset
    

    Where you wanted :

    encryptedLetter = ( (letter - firstLetterOffset) + key[position % keyLength] ) % 26 + firstLetterOffset
    

    Conclusion : you need to put more parenthese to specify in which order you which to evaluate your expression.


    In addition you took the letter number for the text character but not for the key !

    Correct expression

    encryptedLetter = ( (letter - firstLetterOffset) + key[position % keyLength] - firstLetterOffset ) % 26 + firstLetterOffset
    

    Demonstration in javascript