Search code examples
javavigenere

ASCII Vigenere cipher implementation in java


This is about an assignment I got from my programming instructor. We are to implement the vigenere cipher for all printable ASCII codes and run tests with it.

The vigenere cipher is a polyalphabetic cipher using multiple caesar ciphers with a shift of one. Also see Wikipedia

I implemented my vigenere as below, but the tests in my assignment do not produce the required output for my implementation.

I did a search, but it seems as if ASCII implementations of this are quite sparse. Is there an obvious error in my code I'm not seeing?

public String encrypt(String plaintext) {

    String cipherText = "";
    for (int i = 0; i < plaintext.length();  i++) {
        char c = plaintext.charAt(i);

        // vigenere for the letters A-Z is defined as vigenere(m) = m[i] + k[i] % 26
        // where m[i] is the message and k[i] is the key.
        //
        // For ASCII support, as printable space starts at 32, 
        // subtract 2*32 from the sum of keyChar and messageChar to get zero based.
        // Then calculate the modulo of this sum to be sure to stay in bounds.
        // Finally add 32 to the result of the modulo operation to place it in the 32 - 126 range.
        //
        // The key wrapping is implemented as i % _key.length() to restart
        // from the beginning if the end of the key is reached.
        cipherText += (char) ((c + _key.charAt(i % _key.length()) - 64) % 94 + 32);
    }

    return cipherText;
}

Solution

  • The only difference between your code and your comments is you're using % 94 when the range 32 to 126 includes 95 characters.

    Changing your corresponding statement to use modulo 95, and breaking it up a bit:

    int caesar = _key.charAt(i % _key.length()) - 32;
    int sum = c - 32 + caesar;
    cipherText += (char) (sum % 95 + 32);
    

    Then your decryption algorithm can use all the same code, only replacing the second statement above with:

    int sum = c - 32 + (95 - caesar);