mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-12-19 07:00:35 +08:00
72 lines
2.6 KiB
Java
72 lines
2.6 KiB
Java
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<Character, String> BACONIAN_MAP = new HashMap<>();
|
|
private static final Map<String, Character> 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();
|
|
}
|
|
}
|