Simple Bacon's Cipher is easy to see. A message becomes visible A/B groups: HELLO turns into AABBB AABAA ABABA ABABA ABBAB. That is the teaching version.
The advanced version asks a more interesting question: what if the A and B symbols do not look like A and B at all? They could be 0 and 1, X and Y, . and -, or lowercase and uppercase letters hidden inside a harmless-looking sentence.
That is where Bacon's Cipher becomes more than a simple alphabet code. It becomes a bridge between encoding and steganography. Encoding changes the form of a message; steganography hides the existence of the message.
Bacon's great idea was that each letter could be represented by a pattern of two possible forms. Those forms might be written directly as A and B, but they could also be disguised as two fonts, two cases, two styles, two shapes, or two visual treatments.
The message does not have to look encrypted. It can look like ordinary writing. The visible sentence says one thing, while the pattern underneath says another.
Advanced Bacon's Cipher at a glance
| Feature | Advanced Bacon's Cipher |
|---|---|
| Type | Biliteral cipher / steganographic encoding system |
| Main idea | Map each plaintext letter to a five-symbol two-state pattern |
| Default variant | 24-letter classical Bacon alphabet |
| Modern option | 26-letter educational extension with distinct I/J and U/V |
| Code length | 5 symbols per plaintext letter |
| Default pair | A / B |
| Custom pairs | 0 / 1, X / Y, . / -, or other distinct symbols |
| Classical merges | I/J and U/V share codes in 24-letter mode |
| Direct mode | Writes the Bacon pattern visibly |
| Case-based mode | Hides the pattern using uppercase/lowercase styling |
| Raw stream | Continuous clean symbol output without visible separators |
| Carrier requirement | Each hidden letter needs 5 carrier letters |
| Security | Not modern encryption; concealment depends on disguise quality |
| Best use | Learning biliteral encoding, representation layers, steganography, and format fragility |
The advanced tool is best understood as two layers working together.
| Layer | What it does |
|---|---|
| Bacon alphabet | Turns plaintext letters into five-symbol A/B patterns |
| Representation mode | Decides how those patterns are shown or hidden |
The Bacon alphabet creates the pattern. The representation mode decides whether the pattern is obvious or concealed.
What makes this advanced?
Simple Bacon's Cipher shows the Bacon alphabet directly. Advanced Bacon's Cipher explores what else can be done with the same underlying pattern.
| Simple Bacon | Advanced Bacon |
|---|---|
| Shows A/B groups directly | Can disguise the A/B pattern |
| Usually uses one visible output style | Supports multiple representation modes |
| Uses A and B | Can use custom pairs such as 0/1, X/Y, or . / - |
| Mostly teaches the alphabet | Teaches representation and concealment |
| Easy to decode when seen | Harder to notice if hidden well |
The key idea is:
AABBB, 00111, XXYYY, and ..--- can all mean the same thing.
They are different costumes for the same underlying Bacon group. The advanced version separates the message pattern from its visible form.
What is Advanced Bacon's Cipher?
Advanced Bacon's Cipher is a flexible form of the Baconian, or biliteral, cipher. The word biliteral means that the system uses two signs, forms, or symbol classes.
In the simplest version, those signs are just:
A and B
But they do not have to be literal letters. The same Bacon pattern can be rendered using many different pairs.
| Canonical Bacon | Custom pair example |
|---|---|
| A | 0 |
| B | 1 |
So:
AABBB
can be shown as:
00111
or, with . and -:
..---
The meaning is still the same Bacon pattern. Only the representation changes.
The Bacon alphabet
The classical Bacon alphabet uses five-symbol patterns. In 24-letter mode, I/J share one code and U/V share one code.
| Letter | Bacon group |
|---|---|
| A | AAAAA |
| B | AAAAB |
| C | AAABA |
| D | AAABB |
| E | AABAA |
| F | AABAB |
| G | AABBA |
| H | AABBB |
| I/J | ABAAA |
| K | ABAAB |
| L | ABABA |
| M | ABABB |
| N | ABBAA |
| O | ABBAB |
| P | ABBBA |
| Q | ABBBB |
| R | BAAAA |
| S | BAAAB |
| T | BAABA |
| U/V | BAABB |
| W | BABAA |
| X | BABAB |
| Y | BABBA |
| Z | BABBB |
Now take the word:
HIDE
Using the classical 24-letter table:
| Plain letter | Bacon group |
|---|---|
| H | AABBB |
| I | ABAAA |
| D | AAABB |
| E | AABAA |
So the canonical Bacon stream is:
AABBB ABAAA AAABB AABAA
The advanced tool can then render that same stream in several ways.
Direct custom symbols
Direct custom-symbol mode writes the pattern visibly, but replaces A and B with another pair.
If:
A = 0
B = 1
then:
AABBB ABAAA AAABB AABAA
becomes:
00111 01000 00011 00100
If:
A = .
B = -
the same message becomes:
..--- .-... ...-- ..-..
The message can change costume without changing its underlying pattern.
Worked example: direct custom symbols
Let us encode the hidden message:
HIDE
First, build the classical Bacon stream:
| Plain letter | Canonical Bacon |
|---|---|
| H | AABBB |
| I | ABAAA |
| D | AAABB |
| E | AABAA |
So:
HIDE -> AABBB ABAAA AAABB AABAA
Now render with the custom pair 0/1:
| Canonical | Custom |
|---|---|
| AABBB | 00111 |
| ABAAA | 01000 |
| AAABB | 00011 |
| AABAA | 00100 |
The final visible output is:
00111 01000 00011 00100
That output is still not modern encryption. It is simply the Bacon pattern written in a different alphabet.
Hiding a message in case
Case-based hiding uses lowercase and uppercase as the two Bacon forms.
| Case | Bacon value |
|---|---|
| lowercase | A |
| uppercase | B |
A visible carrier text is modified so its casing carries the hidden pattern.
For example, the hidden message:
HIDE
has the Bacon stream:
AABBB ABAAA AAABB AABAA
That stream needs 20 carrier letters, because each hidden letter needs 5 visible letters.
Using the carrier:
the quick brown fox jump
the case-based output becomes:
thE QUiCk brown FOx jUmp
The readable cover text still says "the quick brown fox jump". The hidden casing pattern says HIDE.
Worked example: hiding a message in case
Start with the secret:
HIDE
Use the canonical Bacon stream:
AABBB ABAAA AAABB AABAA
Now apply the rule:
| Bacon symbol | Carrier case |
|---|---|
| A | lowercase |
| B | uppercase |
Apply that pattern to the letters of:
the quick brown fox jump
The result is:
thE QUiCk brown FOx jUmp
To extract the hidden message, read the case pattern from the carrier letters, convert lowercase to A and uppercase to B, group the stream into fives, and decode the Bacon groups.
Carrier length
Case-based hiding consumes visible text. Each hidden plaintext letter needs five alphabetic carrier letters.
| Hidden message length | Required carrier letters |
|---|---|
| 1 letter | 5 carrier letters |
| 5 letters | 25 carrier letters |
| 10 letters | 50 carrier letters |
| 20 letters | 100 carrier letters |
If the carrier is too short, the whole hidden message cannot fit.
The hidden message consumes visible text. That is why carrier length is one of the most important practical limits in Baconian steganography.
24-letter and 26-letter variants
The classical Bacon alphabet uses 24 positions. It combines:
I/J
U/V
So J is encoded as I, and V is encoded as U.
The 26-letter version gives every modern English letter its own pattern.
| Variant | Treatment |
|---|---|
| 24-letter classical | I/J and U/V are merged |
| 26-letter modern | I, J, U, and V are distinct |
The 24-letter version is historically closer. The 26-letter version is more convenient for modern text, but it is best treated as a modern educational extension.
Using the CipherRegister Advanced Bacon's Cipher tool
The Advanced Bacon's Cipher tool lets you experiment with several representation layers.
| Control | What it does |
|---|---|
| Alphabet variant | Switches between 24-letter classical and 26-letter modern modes |
| Direct symbols | Writes the Bacon stream directly using A/B or a custom pair |
| Hidden mode | Applies the stream to carrier text |
| Custom pair | Uses symbols such as 0/1, X/Y, or . / - |
| Raw stream | Shows the continuous Bacon pattern without separators |
| Carrier text | Provides visible text for case-based hiding |
| Carrier length status | Warns when the carrier is too short |
The tool is not only encoding text. It is helping you see the difference between the underlying Bacon pattern and the way that pattern is represented.
What can go wrong?
Advanced Baconian hiding is fragile. It depends on formatting surviving.
| Risk | Why it matters |
|---|---|
| Case normalisation | Converting text to lowercase destroys case-based hiding |
| Font changes | Replacing fonts may erase font-based hiding |
| Copy and paste | Some platforms strip formatting |
| Carrier too short | The hidden message cannot fit |
| Wrong alphabet variant | 24-letter and 26-letter mappings disagree |
| Ambiguous custom symbols | Similar-looking symbols can be misread |
| Visible pattern | If the A/B structure is obvious, decoding is easy |
For example:
thE QUiCk brown FOx jUmp
contains a hidden pattern. But:
the quick brown fox jump
does not. The hidden data has been erased.
Security and limitations
Advanced Bacon's Cipher is not modern encryption.
Its concealment depends on the hidden pattern not being noticed and not being destroyed. Once the two-state pattern is suspected, extracting it is usually straightforward.
| Limitation | Why it matters |
|---|---|
| No strong secret key | The table is usually known |
| Formatting is fragile | Hidden patterns can be stripped or normalised |
| Pattern may be detectable | Unusual casing or styling can draw attention |
| Low capacity | Five carrier letters are needed per hidden letter |
| Not authenticated | Changes may go undetected |
The system is educational and historically fascinating. It is not suitable for protecting passwords, private messages, financial information, API keys, or sensitive personal data.
Related ciphers and encodings
| Cipher or system | Relationship |
|---|---|
| Simple Bacon's Cipher | Shows the visible A/B alphabet directly |
| Binary | Also represents information with two possible states |
| Base32 | Uses fixed-size groups in a modern encoding context |
| Morse code | Uses two signal types, though with variable-length patterns |
| Tap Code | Hides letters in counted physical signals |
| Steganography | Hides messages inside another carrier |
Advanced Bacon sits at the boundary between code and concealment.
A simple Python Advanced Bacon example
Advanced Bacon is a good programming example because the implementation has two layers: build the canonical Bacon stream, then render that stream using a chosen representation.
Python exampleShow code
BACON_24 = {
"A": "AAAAA",
"B": "AAAAB",
"C": "AAABA",
"D": "AAABB",
"E": "AABAA",
"F": "AABAB",
"G": "AABBA",
"H": "AABBB",
"I": "ABAAA",
"K": "ABAAB",
"L": "ABABA",
"M": "ABABB",
"N": "ABBAA",
"O": "ABBAB",
"P": "ABBBA",
"Q": "ABBBB",
"R": "BAAAA",
"S": "BAAAB",
"T": "BAABA",
"U": "BAABB",
"W": "BABAA",
"X": "BABAB",
"Y": "BABBA",
"Z": "BABBB",
}
BACON_26 = {
letter: format(index, "05b").replace("0", "A").replace("1", "B")
for index, letter in enumerate("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
}
def get_table(variant="24"):
if variant == "24":
return BACON_24
if variant == "26":
return BACON_26
raise ValueError("Variant must be '24' or '26'.")
def normalise_letter(char, variant="24"):
char = char.upper()
if variant == "24":
if char == "J":
return "I"
if char == "V":
return "U"
return char
def plaintext_to_bacon_stream(text, variant="24"):
table = get_table(variant)
groups = []
for char in text:
if char.isalpha():
letter = normalise_letter(char, variant)
groups.append(table[letter])
return "".join(groups)
def render_stream(stream, symbol_a="A", symbol_b="B", group_size=5):
rendered = []
for char in stream:
if char == "A":
rendered.append(symbol_a)
else:
rendered.append(symbol_b)
groups = []
joined = "".join(rendered)
for index in range(0, len(joined), group_size):
groups.append(joined[index:index + group_size])
return " ".join(groups)
def encode_direct(text, variant="24", symbol_a="A", symbol_b="B"):
stream = plaintext_to_bacon_stream(text, variant)
return render_stream(stream, symbol_a, symbol_b, group_size=5)
def decode_direct(encoded, variant="24", symbol_a="A", symbol_b="B"):
table = get_table(variant)
reverse_table = {value: key for key, value in table.items()}
canonical = []
for char in encoded:
if char == symbol_a:
canonical.append("A")
elif char == symbol_b:
canonical.append("B")
stream = "".join(canonical)
if len(stream) % 5 != 0:
raise ValueError("Encoded stream must contain complete five-symbol groups.")
output = []
for index in range(0, len(stream), 5):
group = stream[index:index + 5]
output.append(reverse_table.get(group, "?"))
return "".join(output)
def hide_in_case(secret_text, carrier_text, variant="24"):
stream = plaintext_to_bacon_stream(secret_text, variant)
carrier_letters = [char for char in carrier_text if char.isalpha()]
if len(carrier_letters) < len(stream):
raise ValueError("Carrier text does not contain enough letters.")
output = []
stream_index = 0
for char in carrier_text:
if char.isalpha() and stream_index < len(stream):
if stream[stream_index] == "A":
output.append(char.lower())
else:
output.append(char.upper())
stream_index += 1
else:
output.append(char)
return "".join(output)
def extract_from_case(carrier_text, hidden_letters, variant="24"):
table = get_table(variant)
reverse_table = {value: key for key, value in table.items()}
needed_symbols = hidden_letters * 5
stream = []
for char in carrier_text:
if char.isalpha() and len(stream) < needed_symbols:
if char.isupper():
stream.append("B")
else:
stream.append("A")
if len(stream) < needed_symbols:
raise ValueError("Carrier text does not contain enough letters.")
output = []
joined = "".join(stream)
for index in range(0, len(joined), 5):
group = joined[index:index + 5]
output.append(reverse_table.get(group, "?"))
return "".join(output)
# Example
secret = "HIDE"
carrier = "the quick brown fox jump"
direct = encode_direct(secret, symbol_a="0", symbol_b="1")
decoded = decode_direct(direct, symbol_a="0", symbol_b="1")
hidden = hide_in_case(secret, carrier)
extracted = extract_from_case(hidden, hidden_letters=4)
print("Secret :", secret)
print("Direct 0/1 :", direct)
print("Decoded direct :", decoded)
print("Carrier :", carrier)
print("Hidden carrier :", hidden)
print("Extracted :", extracted)
Expected output:
Secret : HIDE
Direct 0/1 : 00111 01000 00011 00100
Decoded direct : HIDE
Carrier : the quick brown fox jump
Hidden carrier : thE QUiCk brown FOx jUmp
Extracted : HIDE
The important distinction is that plaintext_to_bacon_stream creates the meaning-bearing pattern, while render_stream or hide_in_case decides how that pattern appears.
Common questions about Advanced Bacon's Cipher
Is Advanced Bacon's Cipher secure?
No. It is not modern encryption. It can hide a message from casual view if the representation is subtle, but once the pattern is suspected, extraction and decoding are usually straightforward.
Why does each letter use five symbols?
Because five positions with two choices gives:
2^5 = 32
possible patterns. That is enough for 24 letters, 26 letters, and some reserved patterns if a tool defines them carefully.
Can A and B be replaced with other symbols?
Yes. If A = 0 and B = 1, then AABBB becomes 00111. If A = . and B = -, then AABBB becomes ..---.
The underlying Bacon group is the same. Only the rendering changes.
How does case-based Bacon hiding work?
Case-based hiding uses lowercase and uppercase as the two Bacon forms. A visible carrier text is modified so its casing carries the hidden pattern.
The reader extracts the casing, converts it back to A/B, groups it into fives, and decodes the hidden message.
Why can case-based hiding be destroyed?
Because many systems normalise text case. If a hidden message depends on lowercase and uppercase, then any process that converts the text to all-lowercase or all-uppercase destroys the A/B pattern.
How long does the carrier text need to be?
Each hidden plaintext letter requires five carrier letters. A 10-letter hidden message requires 50 alphabetic carrier letters.
What is the raw symbol stream?
The raw symbol stream is the continuous Bacon pattern without visible separators, punctuation, or formatting.
For HIDE, the grouped form is:
AABBB ABAAA AAABB AABAA
and the raw stream is:
AABBBABAAAAAABBAABAA
Why Advanced Bacon's Cipher still matters
Advanced Bacon's Cipher should not be used to protect serious secrets. Not passwords. Not private messages. Not financial information. Not API keys. Not personal data. Not recovery phrases.
It is too fragile, too recognisable once suspected, and too far from modern authenticated encryption.
But it still earns its place.
It shows how letters can become five-symbol binary-style patterns. It shows how the same underlying message can be rendered as A/B, 0/1, X/Y, dots/dashes, or case changes. It shows why representation and meaning are not the same thing.
It also shows why formatting can carry information, and why that information can vanish when formatting is normalised.
Simple Bacon says: here is an A/B code, decode it. Advanced Bacon says: look closer. The real message may be in the pattern underneath.
That is why Advanced Bacon's Cipher still matters. Not because it is secure by modern standards. Because it teaches the difference between visible text, encoded data, and hidden communication.
Try the Advanced Bacon's Cipher tool
Open the Advanced Bacon's Cipher tool and try a short hidden message:
HIDE
Render it as direct A/B:
AABBB ABAAA AAABB AABAA
Then switch to a custom pair such as 0/1:
00111 01000 00011 00100
Then try a case-based carrier:
the quick brown fox jump
and watch it become:
thE QUiCk brown FOx jUmp
Use the tool to switch between 24-letter classical and 26-letter modern alphabets, render Bacon patterns with custom pairs, inspect the raw stream, test carrier text length, and see how fragile hidden formatting can be.