Search code examples
ccs50vigenere

Got stuck in the final part of a program for encryption in Vigenere


I am attending the online course cs50 on Edx and I have an assignment in which I have to create a program where the user enters a keyword ( used then for encryption ) and a string that needs to be encrypted in Vigenere cipher.

Vigenere works by encrypting a text following a keyword: for example if my string is "Hello" and my keyword is "abc" : a is equal to 0 in alphabetical characters, b to 1, and c to 2; so the letter h in the string is encrypted without switching characters ( s letter a in the keyword is = 0), the letter e is switched by one position and is encrypted to f, and so on. If the keyword has a length less than that of the string (like in this case) the encryption has to use again the first character of the keyword and this is my problem.

In fact, I think I implemented well the whole program but I am not sure how to take into consideration if a keyword has less characters than the string entered. The program is now returning only the first char of my string encrypted and the first char not encrypted and then it stops.
I do not ask for a complete solution, but I just want to understand how I can solve my program problem.

Here is my program:

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

int vigenere_low( char c )
{
    int v = c - 'a';
    return v;
}

int vigenere_up( char c )
{
    int v = c - 'A';
    return v;
}

int keyword_low( char c )
{
    int k = c - 'a';
    return k;
}

int keyword_up( char c )
{
    int k = c - 'A';
    return k;
}


int main( int argc, string argv[] )
{
    string p;
    string keyword = argv[1];

    if ( argc != 2 )
    {
        printf("Usage: ./vigenere keyword\n");
        return 1;
    }

    for ( int i = 0, n = strlen(keyword); i < n; i++ )
    {
        if ( !isalpha( keyword[i]) )
        {
            printf("Usage: ./vigenere keyword(alphabetical) \n");
            return 1;
        }
    }

    p = GetString();
    int j = 0;


    for ( int i = 0, n = strlen( p ); i < n; i++ ) 
    {

        if ( isalpha( p[i]) )
            {


              if ( islower( p[i]) )
               {
                 if ( islower( keyword[j]) )
                  {
                    int a = (( vigenere_low( p[i]) + keyword_low( keyword[j]) ) % 26 ) + 'a';
                    printf("%c", a);
                    j++;
                  }
                  else
                  {
                    int a = (( vigenere_low( p[i]) + keyword_up( keyword[j]) ) % 26 ) + 'a';
                    printf("%c", a);;
                    j++;
                  }

                }
               if ( isupper( p[i]) )
                {
                 if ( islower( keyword[j]) )
                   {
                     int a = (( vigenere_up( p[i]) + keyword_low( keyword[j]) ) % 26 ) + 'A';
                     printf("%c", a);
                     j++;
                   }
                 else
                   {
                    int a = (( vigenere_up( p[i]) + keyword_up( keyword[j]) ) % 26 ) + 'A';
                    printf("%c", a);
                    j++;
                   }

                }
        else
        {
            printf("%c", p[i] );
        }



    }

    return 0;
    }
}

Solution

  • ... not sure how to take into consideration if a keyword has less characters than the string entered.

    Accessing keyword[j] beyond the end of keyword[] is bad. (Undefined behavior). This happens with OP's code when the key is shorter than the alpha part of the message.

    Simply re-use the keyword[] string as needed. Hint: reset j.

    Mouse over for answer.

    int j_length = strlen(keyword);
    ...
    j++;
    if (j >= j_length) j = 0;