11package com .thealgorithms .ciphers ;
22
33/**
4- * A Java implementation of Vigenere Cipher.
4+ * A Java implementation of the Vigenère Cipher.
5+ *
6+ * The Vigenère Cipher is a polyalphabetic substitution cipher that uses a
7+ * keyword to shift letters in the plaintext by different amounts, depending
8+ * on the corresponding character in the keyword. It wraps around the alphabet,
9+ * ensuring the shifts are within 'A'-'Z' or 'a'-'z'.
10+ *
11+ * Non-alphabetic characters (like spaces, punctuation) are kept unchanged.
12+ *
13+ * Encryption Example:
14+ * - Plaintext: "Hello World!"
15+ * - Key: "suchsecret"
16+ * - Encrypted Text: "Zynsg Yfvev!"
17+ *
18+ * Decryption Example:
19+ * - Ciphertext: "Zynsg Yfvev!"
20+ * - Key: "suchsecret"
21+ * - Decrypted Text: "Hello World!"
22+ *
23+ * Wikipedia Reference:
24+ * <a href="https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher">Vigenère Cipher - Wikipedia</a>
525 *
626 * @author straiffix
727 * @author beingmartinbmc
828 */
929public class Vigenere {
1030
31+ /**
32+ * Encrypts a given message using the Vigenère Cipher with the specified key.
33+ * Steps:
34+ * 1. Iterate over each character in the message.
35+ * 2. If the character is a letter, shift it by the corresponding character in the key.
36+ * 3. Preserve the case of the letter.
37+ * 4. Preserve non-alphabetic characters.
38+ * 5. Move to the next character in the key (cyclic).
39+ * 6. Return the encrypted message.
40+ *
41+ * @param message The plaintext message to encrypt.
42+ * @param key The keyword used for encryption.
43+ * @throws IllegalArgumentException if the key is empty.
44+ * @return The encrypted message.
45+ */
1146 public String encrypt (final String message , final String key ) {
12- StringBuilder result = new StringBuilder ();
47+ if (key .isEmpty ()) {
48+ throw new IllegalArgumentException ("Key cannot be empty." );
49+ }
1350
51+ StringBuilder result = new StringBuilder ();
1452 int j = 0 ;
1553 for (int i = 0 ; i < message .length (); i ++) {
1654 char c = message .charAt (i );
@@ -20,17 +58,35 @@ public String encrypt(final String message, final String key) {
2058 } else {
2159 result .append ((char ) ((c + key .toLowerCase ().charAt (j ) - 2 * 'a' ) % 26 + 'a' ));
2260 }
61+ j = ++j % key .length ();
2362 } else {
2463 result .append (c );
2564 }
26- j = ++j % key .length ();
2765 }
2866 return result .toString ();
2967 }
3068
69+ /**
70+ * Decrypts a given message encrypted with the Vigenère Cipher using the specified key.
71+ * Steps:
72+ * 1. Iterate over each character in the message.
73+ * 2. If the character is a letter, shift it back by the corresponding character in the key.
74+ * 3. Preserve the case of the letter.
75+ * 4. Preserve non-alphabetic characters.
76+ * 5. Move to the next character in the key (cyclic).
77+ * 6. Return the decrypted message.
78+ *
79+ * @param message The encrypted message to decrypt.
80+ * @param key The keyword used for decryption.
81+ * @throws IllegalArgumentException if the key is empty.
82+ * @return The decrypted plaintext message.
83+ */
3184 public String decrypt (final String message , final String key ) {
32- StringBuilder result = new StringBuilder ();
85+ if (key .isEmpty ()) {
86+ throw new IllegalArgumentException ("Key cannot be empty." );
87+ }
3388
89+ StringBuilder result = new StringBuilder ();
3490 int j = 0 ;
3591 for (int i = 0 ; i < message .length (); i ++) {
3692 char c = message .charAt (i );
@@ -40,11 +96,10 @@ public String decrypt(final String message, final String key) {
4096 } else {
4197 result .append ((char ) ('z' - (25 - (c - key .toLowerCase ().charAt (j ))) % 26 ));
4298 }
99+ j = ++j % key .length ();
43100 } else {
44101 result .append (c );
45102 }
46-
47- j = ++j % key .length ();
48103 }
49104 return result .toString ();
50105 }
0 commit comments