Bacon’s cipher or the Baconian cipher is a method of steganography (a method of hiding a secret message as opposed to just a cipher) devised by Francis Bacon in 1605. A message is concealed in the presentation of text, rather than its content. The Baconian cipher is a substitution cipher in which each letter is replaced by a sequence of 5 characters. In the original cipher, these were sequences of ‘A’s and ‘B’s e.g. the letter ‘D’ was replaced by ‘aaabb’, the letter ‘O’ was replaced by ‘abbab’ etc.
Each letter is assigned to a string of five binary digits. These could be the letters ‘A’ and ‘B’, the numbers 0 and 1 or whatever else you may desire.
There are 2 kinds of Baconian ciphers –
- The 24 letter cipher: In which 2 pairs of letters (I, J) & (U, V) have same ciphertexts.
Letter |
Code |
Binary |
A |
aaaaa |
00000 |
B |
aaaab |
00001 |
C |
aaaba |
00010 |
D |
aaabb |
00011 |
E |
aabaa |
00100 |
F |
aabab |
00101 |
G |
aabba |
00110 |
H |
aabbb |
00111 |
I, J |
abaaa |
01000 |
K |
abaab |
01001 |
L |
ababa |
01010 |
M |
ababb |
01011 |
|
Letter |
Code |
Binary |
N |
abbaa |
01100 |
O |
abbab |
01101 |
P |
abbba |
01110 |
Q |
abbbb |
01111 |
R |
baaaa |
10000 |
S |
baaab |
10001 |
T |
baaba |
10010 |
U, V |
baabb |
10011 |
W |
babaa |
10100 |
X |
babab |
10101 |
Y |
babba |
10110 |
Z |
babbb |
10111 |
|
- The 26 letter cipher: In which all letters have unique ciphertexts.
Letter |
Code |
Binary |
A |
aaaaa |
00000 |
B |
aaaab |
00001 |
C |
aaaba |
00010 |
D |
aaabb |
00011 |
E |
aabaa |
00100 |
F |
aabab |
00101 |
G |
aabba |
00110 |
H |
aabbb |
00111 |
I |
abaaa |
01000 |
J |
abaab |
01001 |
K |
ababa |
01010 |
L |
ababb |
01011 |
M |
abbaa |
01100 |
|
Letter |
Code |
Binary |
N |
abbab |
01101 |
O |
abbba |
01110 |
P |
abbbb |
01111 |
Q |
baaaa |
10000 |
R |
baaab |
10001 |
S |
baaba |
10010 |
T |
baabb |
10011 |
U |
babaa |
10100 |
V |
babab |
10101 |
W |
babba |
10110 |
X |
babbb |
10111 |
Y |
bbaaa |
11000 |
Z |
bbaab |
11001 |
|
Encryption
We will extract a single character from the string and if its not a space then we will replace it with its corresponding ciphertext according to the cipher we are using else we will add a space and repeat it until we reach the end of the string. For example ‘A’ is replaced with ‘aaaaa’
Decryption
We will extract every set of 5 characters from the encrypted string and check if the first character in that set of 5 characters is a space. If not we will lookup its corresponding plaintext letter from the cipher, replace it and increment the index of character by 5 (to get the set of next 5 characters) else if its a space we add a space and repeat a process by incrementing the current index of character by 1
Approach
In Python, we can map key-value pairs using a data structure called a dictionary. We are going to use just one dictionary in which we will map the plaintext-ciphertext pairs as key-value pairs. For encryption we will simply lookup the corresponding ciphertext by accessing the value using the corresponding plaintext character as key. In decryption we will extract every 5 set of ciphertext characters and retrieve their keys from the dictionary using them as the corresponding value. For an accurate decryption we will use the 26 letter cipher. If you are not coding in python then you can come up with your own approach.
Implementation:
Python
lookup = { 'A' : 'aaaaa' , 'B' : 'aaaab' , 'C' : 'aaaba' , 'D' : 'aaabb' , 'E' : 'aabaa' ,
'F' : 'aabab' , 'G' : 'aabba' , 'H' : 'aabbb' , 'I' : 'abaaa' , 'J' : 'abaab' ,
'K' : 'ababa' , 'L' : 'ababb' , 'M' : 'abbaa' , 'N' : 'abbab' , 'O' : 'abbba' ,
'P' : 'abbbb' , 'Q' : 'baaaa' , 'R' : 'baaab' , 'S' : 'baaba' , 'T' : 'baabb' ,
'U' : 'babaa' , 'V' : 'babab' , 'W' : 'babba' , 'X' : 'babbb' , 'Y' : 'bbaaa' , 'Z' : 'bbaab' }
def encrypt(message):
cipher = ''
for letter in message:
if (letter ! = ' ' ):
cipher + = lookup[letter]
else :
cipher + = ' '
return cipher
def decrypt(message):
decipher = ''
i = 0
while True :
if (i < len (message) - 4 ):
substr = message[i:i + 5 ]
if (substr[ 0 ] ! = ' ' ):
decipher + = list (lookup.keys()
)[ list (lookup.values()).index(substr)]
i + = 5
else :
decipher + = ' '
i + = 1
else :
break
return decipher
def main():
message = "Geeks for Geeks"
result = encrypt(message.upper())
print (result)
message = "AABAAABBABABAABABBBABBAAA"
result = decrypt(message.lower())
print (result)
if __name__ = = '__main__' :
main()
|
Output
aabbaaabaaaabaaabababaaba aabababbbabaaab aabbaaabaaaabaaabababaaba
ENJOY
Complexity Analysis: The Baconian cipher is a simple substitution cipher that replaces each letter of the plaintext with a corresponding five-character code. The cipher has a fixed dictionary of 26 codes for each letter of the alphabet, and can handle both upper and lowercase letters, as well as spaces. The encrypt() function has a time complexity of O(n) and the decrypt() function has a time complexity of O(n^2), where n is the length of the input string. Both functions have a space complexity of O(n), where n is the length of the input string.
Analysis: This cipher offers very little communication security, as it is a substitution cipher. As such all the methods used to cryptanalyse substitution ciphers can be used to break Baconian ciphers. The main advantage of the cipher is that it allows hiding the fact that a secret message has been sent at all.
Last Updated :
03 May, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...