From f42858e5de8f0b46e090e1756b5fda81af2b0143 Mon Sep 17 00:00:00 2001 From: bennybebo Date: Mon, 21 Oct 2024 13:59:12 -0400 Subject: [PATCH 1/4] Added BaconianCipher.java and BaconianCipherTest.java --- .../thealgorithms/ciphers/BaconianCipher.java | 71 +++++++++++++++++++ .../ciphers/BaconianCipherTest.java | 34 +++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/main/java/com/thealgorithms/ciphers/BaconianCipher.java create mode 100644 src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java diff --git a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java new file mode 100644 index 000000000000..3d2ca88b1bc5 --- /dev/null +++ b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java @@ -0,0 +1,71 @@ +package com.thealgorithms.ciphers; + +import java.util.HashMap; +import java.util.Map; + +/** + * The Baconian Cipher is a substitution cipher where each letter is represented + * by a group of five binary digits (A's and B's). It can also be used to hide + * messages within other texts, making it a simple form of steganography. + * https://en.wikipedia.org/wiki/Bacon%27s_cipher + * + * @author Bennybebo + */ +public class BaconianCipher { + + private static final Map BACONIAN_MAP = new HashMap<>(); + private static final Map REVERSE_BACONIAN_MAP = new HashMap<>(); + + static { + // Initialize the Baconian cipher mappings + String[] baconianAlphabet = { "AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"}; + char letter = 'A'; + for (String code : baconianAlphabet) { + BACONIAN_MAP.put(letter, code); + REVERSE_BACONIAN_MAP.put(code, letter); + letter++; + } + + // Handle I/J as the same letter + BACONIAN_MAP.put('I', BACONIAN_MAP.get('J')); + REVERSE_BACONIAN_MAP.put(BACONIAN_MAP.get('I'), 'I'); + } + + /** + * Encrypts the given plaintext using the Baconian cipher. + * + * @param plaintext The plaintext message to encrypt. + * @return The ciphertext as a binary (A/B) sequence. + */ + public String encrypt(String plaintext) { + StringBuilder ciphertext = new StringBuilder(); + plaintext = plaintext.toUpperCase().replaceAll("[^A-Z]", ""); // Remove non-letter characters + + for (char letter : plaintext.toCharArray()) { + ciphertext.append(BACONIAN_MAP.get(letter)); + } + + return ciphertext.toString(); + } + + /** + * Decrypts the given ciphertext encoded in binary (A/B) format using the Baconian cipher. + * + * @param ciphertext The ciphertext to decrypt. + * @return The decrypted plaintext message. + */ + public String decrypt(String ciphertext) { + StringBuilder plaintext = new StringBuilder(); + + for (int i = 0; i < ciphertext.length(); i += 5) { + String code = ciphertext.substring(i, i + 5); + if (REVERSE_BACONIAN_MAP.containsKey(code)) { + plaintext.append(REVERSE_BACONIAN_MAP.get(code)); + } else { + throw new IllegalArgumentException("Invalid Baconian code: " + code); + } + } + + return plaintext.toString(); + } +} diff --git a/src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java b/src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java new file mode 100644 index 000000000000..da1913582103 --- /dev/null +++ b/src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java @@ -0,0 +1,34 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class BaconianCipherTest { + + BaconianCipher baconianCipher = new BaconianCipher(); + + @Test + void baconianCipherEncryptTest() { + // given + String plaintext = "MEET AT DAWN"; + + // when + String cipherText = baconianCipher.encrypt(plaintext); + + // then + assertEquals("ABBAAAABAAAABAABAABBAAAAABAABBAAABBAAAAABABBAABBAB", cipherText); + } + + @Test + void baconianCipherDecryptTest() { + // given + String ciphertext = "ABBAAAABAAAABAABAABBAAAAABAABBAAABBAAAAABABBAABBAB"; + + // when + String plainText = baconianCipher.decrypt(ciphertext); + + // then + assertEquals("MEETATDAWN", plainText); + } +} From 8ff6fd03b1067b85b69c8b1452179411126d0317 Mon Sep 17 00:00:00 2001 From: bennybebo Date: Mon, 21 Oct 2024 14:06:09 -0400 Subject: [PATCH 2/4] Fix Checkstyle --- src/main/java/com/thealgorithms/ciphers/BaconianCipher.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java index 3d2ca88b1bc5..1055b2fbe6ab 100644 --- a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java @@ -18,7 +18,7 @@ public class BaconianCipher { static { // Initialize the Baconian cipher mappings - String[] baconianAlphabet = { "AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"}; + String[] baconianAlphabet = {"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"}; char letter = 'A'; for (String code : baconianAlphabet) { BACONIAN_MAP.put(letter, code); @@ -33,7 +33,7 @@ public class BaconianCipher { /** * Encrypts the given plaintext using the Baconian cipher. - * + * * @param plaintext The plaintext message to encrypt. * @return The ciphertext as a binary (A/B) sequence. */ @@ -50,7 +50,7 @@ public String encrypt(String plaintext) { /** * Decrypts the given ciphertext encoded in binary (A/B) format using the Baconian cipher. - * + * * @param ciphertext The ciphertext to decrypt. * @return The decrypted plaintext message. */ From 1431e7f4915542fe047ca9a1642528c1dce12ba0 Mon Sep 17 00:00:00 2001 From: bennybebo Date: Mon, 21 Oct 2024 14:06:33 -0400 Subject: [PATCH 3/4] Fix Checkstyle --- src/main/java/com/thealgorithms/ciphers/BaconianCipher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java index 1055b2fbe6ab..9791a2a51b04 100644 --- a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java @@ -8,7 +8,7 @@ * by a group of five binary digits (A's and B's). It can also be used to hide * messages within other texts, making it a simple form of steganography. * https://en.wikipedia.org/wiki/Bacon%27s_cipher - * + * * @author Bennybebo */ public class BaconianCipher { From 4c3ba7c28ce09df7a3be5bb935b4e191524a3499 Mon Sep 17 00:00:00 2001 From: bennybebo Date: Mon, 21 Oct 2024 14:08:19 -0400 Subject: [PATCH 4/4] Fix --- src/main/java/com/thealgorithms/ciphers/BaconianCipher.java | 2 +- src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java index 9791a2a51b04..16dfd6e674af 100644 --- a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java @@ -18,7 +18,7 @@ public class BaconianCipher { static { // Initialize the Baconian cipher mappings - String[] baconianAlphabet = {"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"}; + String[] baconianAlphabet = {"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"}; char letter = 'A'; for (String code : baconianAlphabet) { BACONIAN_MAP.put(letter, code); diff --git a/src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java b/src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java index da1913582103..bb1ae5a7e4c2 100644 --- a/src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java +++ b/src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java @@ -6,7 +6,7 @@ class BaconianCipherTest { - BaconianCipher baconianCipher = new BaconianCipher(); + BaconianCipher baconianCipher = new BaconianCipher(); @Test void baconianCipherEncryptTest() {