Vigenère Cipher in Java
The Vigenère cipher is a classic method of encryption that utilizes a keyword to create a more complex substitution, making it a fascinating subject for both cryptography enthusiasts and Java programmers. This article will explain how the Vigenère Cipher works and how to implement both its encryption and decryption in Java.
1. How the Vigenère Cipher Works
The Vigenère cipher offers a step up from the simple Caesar cipher. The Vigenère Cipher uses a polyalphabetic substitution cipher that uses a keyword to determine the shift for each letter in the plaintext. Here’s a step-by-step explanation:
- Keyword Repetition: The keyword is repeated or truncated to match the length of the plaintext.
- Shifting: Each letter of the plaintext is shifted along the alphabet by the number of positions indicated by the corresponding letter of the keyword.
- Modulo Operation: The alphabet is treated as a circular structure using modulo 26 arithmetic to ensure that the shifts wrap around correctly.
For example, if the plaintext is “HELLO” and the keyword is “KEY“:
- The keyword is repeated to match the length of the plaintext: “KEYKE“.
- Each letter in “HELLO” is shifted by the corresponding letter in “KEYKE” (H by K, E by E, L by Y, and so on).
Here is a graphical representation of the Vigenère Cipher illustrating how the keyword shifts the plaintext letters to produce the ciphertext.
This representation shows how each letter in the plaintext is shifted according to the corresponding letter in the keyword.
2. Implementing the Vigenère Cipher in Java
2.1 Encryption
Here’s a Java implementation of the Vigenere Cipher encryption:
public class VigenereCipher { public static String encrypt(String plaintext, String keyword) { StringBuilder ciphertext = new StringBuilder(); keyword = keyword.toUpperCase(); plaintext = plaintext.toUpperCase(); for (int i = 0, j = 0; i < plaintext.length(); i++) { char letter = plaintext.charAt(i); if (letter < 'A' || letter > 'Z') { // Non-alphabetic characters are not changed ciphertext.append(letter); continue; } // Shift the plaintext letter by the keyword letter char shift = keyword.charAt(j % keyword.length()); char encryptedLetter = (char)((letter + shift - 2 * 'A') % 26 + 'A'); ciphertext.append(encryptedLetter); j++; } return ciphertext.toString(); } public static void main(String[] args) { String plaintext = "ATTACK AT DAWN"; String keyword = "SECURE"; String ciphertext = encrypt(plaintext, keyword); System.out.println("Plaintext: " + plaintext); System.out.println("Keyword: " + keyword); System.out.println("Ciphertext: " + ciphertext); } }
The above Java code implements the Vigenère Cipher for encryption. The encrypt
method converts plaintext to ciphertext by shifting each letter according to the corresponding letter in the keyword. Non-alphabetic characters are ignored and appended unchanged.
Output is:
2.2 Decryption
To reverse the process, the decryption method needs to shift each letter in the ciphertext back by the corresponding letter in the keyword:
public class VigenereCipher { public static String decrypt(String ciphertext, String keyword) { StringBuilder plaintext = new StringBuilder(); keyword = keyword.toUpperCase(); ciphertext = ciphertext.toUpperCase(); for (int i = 0, j = 0; i < ciphertext.length(); i++) { char letter = ciphertext.charAt(i); if (letter < 'A' || letter > 'Z') { // Non-alphabetic characters are not changed plaintext.append(letter); continue; } // Shift the ciphertext letter back by the keyword letter char shift = keyword.charAt(j % keyword.length()); char decryptedLetter = (char)((letter - shift + 26) % 26 + 'A'); plaintext.append(decryptedLetter); j++; } return plaintext.toString(); } public static void main(String[] args) { String ciphertext = "SXVUTO SX FUNR"; String keyword = "SECURE"; String plaintext = decrypt(ciphertext, keyword); System.out.println("Ciphertext: " + ciphertext); System.out.println("Keyword: " + keyword); System.out.println("Plaintext: " + plaintext); } }
The decrypt
method reverses this process by shifting each letter of the ciphertext back by the corresponding letter in the keyword.
Both methods ensure the keyword is repeated to match the length of the text.
2.3 Full Example Code
Here is the full example code combining both encryption and decryption:
public class VigenereCipher { public static String encrypt(String plaintext, String keyword) { StringBuilder ciphertext = new StringBuilder(); keyword = keyword.toUpperCase(); plaintext = plaintext.toUpperCase(); for (int i = 0, j = 0; i < plaintext.length(); i++) { char letter = plaintext.charAt(i); if (letter < 'A' || letter > 'Z') { // Non-alphabetic characters are not changed ciphertext.append(letter); continue; } // Shift the plaintext letter by the keyword letter char shift = keyword.charAt(j % keyword.length()); char encryptedLetter = (char)((letter + shift - 2 * 'A') % 26 + 'A'); ciphertext.append(encryptedLetter); j++; } return ciphertext.toString(); } public static String decrypt(String ciphertext, String keyword) { StringBuilder plaintext = new StringBuilder(); keyword = keyword.toUpperCase(); ciphertext = ciphertext.toUpperCase(); for (int i = 0, j = 0; i < ciphertext.length(); i++) { char letter = ciphertext.charAt(i); if (letter < 'A' || letter > 'Z') { // Non-alphabetic characters are not changed plaintext.append(letter); continue; } // Shift the ciphertext letter back by the keyword letter char shift = keyword.charAt(j % keyword.length()); char decryptedLetter = (char)((letter - shift + 26) % 26 + 'A'); plaintext.append(decryptedLetter); j++; } return plaintext.toString(); } public static void main(String[] args) { String plaintext = "ATTACK AT DAWN"; String keyword = "SECURE"; String ciphertext = encrypt(plaintext, keyword); String decryptedText = decrypt(ciphertext, keyword); System.out.println("Plaintext: " + plaintext); System.out.println("Keyword: " + keyword); System.out.println("Ciphertext: " + ciphertext); System.out.println("Decrypted Text: " + decryptedText); } }
3. Conclusion
In this article, we delved into the Vigenere Cipher, exploring how to implement it. We covered both the encryption and decryption processes, emphasizing the cipher’s use of a keyword to achieve polyalphabetic substitution. By following the Java implementations provided for both encryption and decryption, we can effectively secure text using this cryptographic technique.
4. Download the Source Code
This was an article on Vigenère Cipher in Java.
You can download the full source code of this example here: Vigenère Cipher in Java