Search code examples
cencryptionvigenere

Negative numbers with modulo operator in 'De-Vigenere' program


I am making a program that decrypts the vigenere cipher. User can only give alphabetical key.

for (int i = 0, counter = strlen(text); i < counter; i++)
    {
        // prints non-alphabetical characters straight away
        if (!isalpha(text[i]))
        {
            printf("%c", text[i]);
        }

        else
        {
            // for index of key
            index = meta % strlen(key);

            if (islower(text[i]))
            {
                // separate cases depending upon case of key
                if (islower(key[index]))
                {
                    printf("%c", (((text[i] - 97) - (key[index] - 97)) % 26) + 97);
                }
                else
                {
                    printf("%c", (((text[i] - 97) - (key[index] - 65)) % 26) + 97);
                }
            }

            else
            {
                if (islower(key[index]))
                {
                    printf("%d", (((text[i] - 65) - (key[index] - 97)) % 26) + 65); 
                }
                else
                {
                    printf("%c", (((text[i] - 65) - (key[index] - 65)) % 26) + 65);
                }
            }
            // incrementing for next key alphabet
            meta++;
        }

Vigenere:

  • Input: MyName

  • key: qwerty

  • output: CuRrfc

De Vigenere:

  • Input: CuRrfc
  • key:qwerty
  • expected output: MyName
  • given output: 3_NaSK

How can I fix it?


Solution

  • The problem is the way the modulus operator deals with negative numbers.

    For some characters you get negative values and the modulus operation then returns a negative value. You want a value in the range [0, 25].

    You can fix it by adding 26 before taking the modulus.

                    printf("%c", (((text[i] - 97) - (key[index] - 97)) % 26) + 97);
    

    would become

                    printf("%c", (((text[i] - 97) - (key[index] - 97) + 26) % 26) + 97);
    

    Change all four rows the same way.