Krill Krill - 3 months ago 12
C Question

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

Answer

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