ccs50vigenere

Vigenere giving wrong result


The task is to give a keyword argument when you run the program, which I saved as a string k then the user inputs text and the program will output that inputted text according to the keyword. A = 0, B = 1, so if the keyword is ABABA and the text is hello, it would output hflmo.

If I run the program giving argv[1] as "abc" then plaintext pt as "hello", I should be getting "hfnlp", but instead I get "hnflv", why doesn't the last letter encipher correctly?

    string k = argv[1];
    int l = strlen(argv[1]);
    printf("plaintext: ");
    string pt = get_string("");
    printf("ciphertext: ");
    for (int i = 0, shift = 0; i < strlen(pt); i++)
    {    
        if (!isalpha(pt[i]))
        {
            printf("%c", pt[i]);
        }
        else
        {
            if (isupper(pt[i]))
            {
                if (isupper(k[shift]))
                {
                    printf("%c", (((pt[i] - 65) + (k[shift % l] - 65)) %26) + 65);
                    shift++;
                }
                else
                {
                    printf("%c", (((pt[i] - 65) + (k[shift % l] - 97)) %26) + 65);
                    shift++;
                }
            }
            else if (islower(pt[i]))
            {
                if (isupper(k[shift]))
                {
                    printf("%c", (((pt[i] - 97) + (k[shift % l] - 65)) %26) + 97);
                    shift++;
                }
                else
                {
                    printf("%c", (((pt[i] - 97) + (k[shift % l] - 97)) %26) + 97);
                    shift++;
                }
            }
        }    
    }                               
    printf("\n");
    return 0;
}    

Solution

  • The lines

    if (isupper(k[shift]))
    

    are missing the modulo calculation. The correct version is:

    if (isupper(k[shift % l]))
    

    It might be clearer if you put this calculation at some central place in the for-loop:

    shift %= l;