Skip to main content
Basic Classic Symmetric Beginner

Bacon's Cipher

Learn about Bacon's cipher, Francis Bacon's 17th-century biliteral system that hides a secret message not by scrambling it, but by encoding it into which of two typefaces each letter of an innocent-looking cover text uses.

PL
Pashalis Laoutaris
August 21, 2026
12 min read

Interactive Bacon's Cipher Visualizer

🔐 Bacon's Cipher Visualizer

5
Enter text and click a button to start!
Biliteral (A/B) Stream
Hidden in Cover Text
HI

Bacon’s Cipher: Hiding the Message in Plain Sight

Introduction

Every cipher covered so far in this series shares one assumption: an observer can see that a message has been encrypted, even if they can’t read it. Francis Bacon’s cipher, devised around 1605, breaks that assumption entirely. It’s not really a cipher in the scrambling sense at all. It’s steganography: a way of hiding a secret message inside an ordinary-looking piece of text, so that anyone glancing at it sees nothing but an innocent sentence. The secret isn’t hidden behind math. It’s hidden behind typography.

Table of Contents

How Bacon’s Cipher Works

Bacon’s cipher, sometimes called the biliteral cipher, works in two independent steps:

  1. Encode each letter of the secret message as a unique sequence of five symbols, using only two distinct symbols (traditionally labeled A and B).
  2. Hide that sequence of A’s and B’s inside an unrelated cover text, by representing “A” and “B” as two visually different presentations of ordinary letters. Classically these are two different typefaces, but modern versions might use bold versus normal text, uppercase versus lowercase, or any other two-way visual distinction.

Anyone who doesn’t know to look for the typographic pattern just reads the cover text as ordinary writing. The secret message is completely invisible unless you know it’s there.

Interactive Visualizer

Try it above. Enter a secret message, watch it get encoded into an A/B stream using the biliteral table, and then watch that stream get hidden inside the cover text below. Bold letters represent “B”; normal letters represent “A”.

The Biliteral Alphabet

Every letter gets a unique 5-symbol code built from just two symbols. Since 2⁵ = 32, five symbols are more than enough to cover the 24-letter alphabet Bacon originally worked with (which, following the convention of his era, treats I/J and U/V as sharing a letter each). Modern puzzle and recreational-cryptography variants sometimes expand the table to a full 26 distinct codes, one per letter, since 32 possible codes leaves plenty of room. The classic table below, with its shared I/J and U/V codes, is the historically original version. It’s the one this article, and the visualizer above, uses throughout.

A = AAAAA   H = AABBB   O = ABBAB   V = BAABB
B = AAAAB   I = ABAAA   P = ABBBA   W = BABAA
C = AAABA   J = ABAAA   Q = ABBBB   X = BABAB
D = AAABB   K = ABAAB   R = BAAAA   Y = BABBA
E = AABAA   L = ABABA   S = BAAAB   Z = BABBB
F = AABAB   M = ABABB   T = BAABA
G = AABBA   N = ABBAA   U = BAABB

A Worked Example

Encoding “HI” using the table above:

  • H → AABBB
  • I → ABAAA

Concatenated: AABBBABAAA (10 symbols, 5 per letter)

Hiding the Message: The Steganographic Step

This is where Bacon’s cipher becomes genuinely different from every other cipher in this series. Every secret letter expands into a 5-symbol code, and each symbol needs exactly one cover-text letter to carry it. So the cover text must be at least five times as long as the secret message. A 2-letter secret like “HI” needs at least 10 cover-text letters; a 20-letter secret needs at least 100. For “AABBBABAAA” (10 symbols, from encoding “HI”), a 10-letter cover text is enough. Using “THEQUICKB” (well, “THEQUICKBROWNFOX…” truncated to the first 10 letters):

Cover:    T  H  E  Q  U  I  C  K  B  R
Bit:      A  A  B  B  B  A  B  A  A  A
Style:  normal normal BOLD BOLD BOLD normal BOLD normal normal normal

Rendered with bold representing “B”: T H E Q U I C K B R. To a casual reader, this just looks like someone got a little heavy-handed with their bold key. To someone who knows to check which letters are bold, it reveals AABBBABAAA, which decodes straight back to “HI”.

Note that the choice of “bold = B” here is entirely arbitrary. It could just as easily have been “normal = B, bold = A” instead, and the message would decode identically once that convention is agreed on in advance. This is exactly why identifying the two styles being used doesn’t automatically reveal the message: there are only two possible ways to assign them to A and B, but both have to be tried.

The bold/normal choice is just one option, too. Uppercase/lowercase works exactly the same way. Encode “HI” as AABBBABAAA into the cover word “HELLOWORLD” (10 letters), with uppercase representing “B” and lowercase representing “A”, and you get heLLOwOrld. Again, this is an ordinary-looking (if oddly capitalized) word that hides the identical 10-symbol stream, decodable back to “HI” the same way.

Decoding

Decoding reverses the process in two steps: first, extract the sequence of A’s and B’s by reading off which typographic style each cover-text letter used; then split that sequence into groups of five and look each group up in the biliteral table to recover the original letters.

Working through the “T H E Q U I C K B R” example above: reading normal-as-A and bold-as-B off each of the ten cover letters in order reproduces the extracted stream A A B B B A B A A A, exactly matching the original “AABBBABAAA.” Splitting that recovered stream into groups of five, “AABBB” and “ABAAA”, and looking each up in the biliteral table gives H and I, recovering “HI.”

The visualizer above handles the second step directly. Paste or type a biliteral A/B stream (like “AABBBABAAA”) into the message field in decode mode, and it will split it into 5-symbol groups and reveal the hidden letters.

Pros and Cons Analysis

Advantages Disadvantages
True Steganography: Unlike every substitution or transposition cipher, an observer doesn’t even know a secret message exists, let alone see obviously scrambled ciphertext Requires 5x the Cover Text: Every secret letter needs five cover-text letters, making long messages require substantial cover material
No Suspicious Ciphertext: A properly executed hidden message looks like completely ordinary writing, unlike a block of random-looking letters The Encoding Itself Is Trivially Weak: Once someone suspects steganography and identifies the two styles, the biliteral table is fixed and public; there’s no key to protect the encoding step itself
Combinable with Any Two-State Distinction: Not limited to typefaces: capitalization, punctuation choices, word length parity, or any other binary signal can carry the hidden bits Detectable Under Scrutiny: Any close, careful reading of the cover text (checking for unusual style-switching patterns) can reveal that something is encoded
Genuinely Different Threat Model: Defeats “obviously encrypted messages get extra scrutiny” in a way no substitution or transposition cipher can No Real-World Security Today: Modern steganography analysis (statistical detection of anomalies) easily catches naive implementations like this one

Cryptanalysis: Detecting Bacon’s Cipher

Because Bacon’s cipher hides its message in presentation rather than in scrambled content, “breaking” it is really a two-part problem: first detecting that something is hidden at all, then decoding it once found.

Detection typically comes from noticing unusual patterns in the two-state signal being used. For example, a careful reader might suspect encoding if font or style changes don’t correlate with any normal editorial reason (like emphasis), or if capitalization patterns don’t follow normal English conventions. Once the two states are identified and their assignment to A/B is guessed (there are only two possible assignments to try), decoding is completely mechanical. The biliteral table is public and fixed, so there’s no cryptographic key protecting the content itself.

This is a fundamentally different weakness profile than the substitution and transposition ciphers earlier in this series: Bacon’s cipher isn’t broken by frequency analysis, but by stylometric or statistical scrutiny of the cover text’s presentation.

Bacon’s Cipher and Binary

Look closely at the biliteral alphabet, and it’s really nothing more than a 5-bit binary encoding, with A standing in for 0 and B for 1. A = 00000, B = 00001, C = 00010, and so on, counting upward in binary order exactly through the alphabet. Francis Bacon devised this system roughly three centuries before Claude Shannon formalized binary information theory. That makes it one of history’s earliest practical demonstrations that any distinguishable two-state signal (ink color, typeface, capitalization, anything at all) can represent arbitrary information, provided you agree on an encoding in advance. That idea underpins essentially all of modern digital computing and communication.

Five bits provide 2⁵ = 32 possible codes, but the classic table only needs 24 of them, leaving eight codes unused. Bacon simply didn’t assign them to anything. A modern implementation could put that spare capacity to use for the ten digits, punctuation, or the full 26-letter alphabet without changing anything else about how the system works.

Modern Relevance

Bacon’s cipher itself secures nothing today, but its core idea is everywhere:

  • Digital steganography directly descends from this concept: hiding data in the least-significant bits of image pixels, in unused fields of file formats, or in subtle timing variations of network packets all follow the same “hide information in an otherwise-innocent two-state signal” principle.
  • Watermarking techniques, used to embed ownership information invisibly into digital media, are conceptually direct descendants of Bacon’s approach.
  • A clear historical illustration that binary encoding predates computers: a valuable teaching point connecting classical cryptography to modern information theory.

Python Implementation

Encoding, hiding, and decoding are three small, independent functions. Hiding uses uppercase for “B” and lowercase for “A”, the same convention as the “heLLOwOrld” example above:

_CODES = ['AAAAA', 'AAAAB', 'AAABA', 'AAABB', 'AABAA', 'AABAB', 'AABBA', 'AABBB',
          'ABAAA', 'ABAAB', 'ABABA', 'ABABB', 'ABBAA', 'ABBAB', 'ABBBA', 'ABBBB',
          'BAAAA', 'BAAAB', 'BAABA', 'BAABB', 'BABAA', 'BABAB', 'BABBA', 'BABBB']
_LETTERS = 'ABCDEFGHIKLMNOPQRSTUWXYZ'  # 24 letters; J and V are aliases, added below

BILITERAL = dict(zip(_LETTERS, _CODES))
BILITERAL['J'] = BILITERAL['I']
BILITERAL['V'] = BILITERAL['U']
REVERSE_BILITERAL = dict(zip(_CODES, _LETTERS))

def encode_biliteral(text):
    text = ''.join(c for c in text.upper() if c.isalpha())
    return ''.join(BILITERAL[c] for c in text)

def decode_biliteral(stream):
    stream = ''.join(c for c in stream.upper() if c in 'AB')
    groups = [stream[i:i + 5] for i in range(0, len(stream), 5)]
    return ''.join(REVERSE_BILITERAL[group] for group in groups)

def hide_in_cover(bits, cover_text):
    """Uppercase carries a 'B', lowercase carries an 'A'. Needs len(cover_text) >= len(bits)."""
    return ''.join(c.upper() if bit == 'B' else c.lower() for c, bit in zip(cover_text, bits))

def extract_bits(hidden_text):
    return ''.join('B' if c.isupper() else 'A' for c in hidden_text)

if __name__ == "__main__":
    secret = "HI"
    cover = "HELLOWORLD"

    bits = encode_biliteral(secret)
    hidden = hide_in_cover(bits, cover)
    extracted_bits = extract_bits(hidden)
    recovered = decode_biliteral(extracted_bits)

    print(f"Secret:    {secret}")
    print(f"Bits:      {bits}")
    print(f"Hidden:    {hidden}")
    print(f"Recovered: {recovered}")

This reproduces the uppercase/lowercase worked example above exactly: HI encodes to the bit stream AABBBABAAA, hides inside “HELLOWORLD” as heLLOwOrld, and decodes straight back to HI.

Limitations

This implementation covers the mechanism, not a realistic deployment:

  • Only one hiding scheme. The code hides bits via letter case, one of several options mentioned above (bold/normal, uppercase/lowercase). A real bold/normal implementation would need a document format capable of representing typographic style, not just plain text.
  • No automatic cover-text generation. hide_in_cover requires a cover text at least as long as the bit stream, supplied by the caller; it doesn’t generate plausible cover text on its own.
  • No detection resistance built in. As the Cryptanalysis section above explains, an unnatural pattern of capitalization is exactly what gives a hidden message away; this code doesn’t attempt to make the hidden pattern statistically inconspicuous.
  • Not intended for real security. The biliteral table is public and fixed, so once someone suspects steganography and identifies the two states, decoding is completely mechanical, regardless of how this code is written.

Conclusion

Bacon’s cipher stands apart from every other cipher in this series because it doesn’t try to make a message unreadable. It tries to make the existence of a message invisible. By encoding each letter as a five-symbol binary-like pattern and hiding that pattern inside the typography of an ordinary cover text, it demonstrates a genuinely different security model: not “can an attacker decode this,” but “can an attacker even tell there’s something to decode.” That distinction, between confidentiality and covertness, remains central to digital steganography and watermarking centuries later. This holds even though Bacon’s specific 17th-century mechanism offers no real security today.

FAQ

What is Bacon’s cipher?

A steganographic system, devised by Francis Bacon, that encodes each letter as a unique 5-symbol sequence built from two symbols (A and B), then hides that sequence inside an unrelated cover text using two visually distinguishable letter styles. Classically these are two typefaces, but any two-state visual distinction works.

Is Bacon’s cipher the same as encryption?

Not exactly. It’s steganography, which hides the existence of a message rather than scrambling its content the way encryption does. The biliteral encoding itself has no secret key; the security comes entirely from the cover text hiding that anything is encoded at all.

How many cover-text letters does a secret message need?

Five cover-text letters per secret letter, since each letter’s code is five symbols long. A 10-letter secret message needs at least 50 cover-text letters.

Its biliteral alphabet is structurally identical to 5-bit binary, with A representing 0 and B representing 1. That makes it one of the earliest documented uses of a two-symbol encoding system, roughly three centuries before binary computing existed.

How can Bacon’s cipher be detected?

By scrutinizing the cover text for unusual patterns in whatever two-state signal is being used (unexplained style switches, irregular capitalization, and so on) that don’t correspond to any normal reason for the variation.

References

  1. Wikipedia. “Bacon’s cipher.” Available at: https://en.wikipedia.org/wiki/Bacon%27s_cipher

  2. Practical Cryptography. “Baconian Cipher.” Available at: http://practicalcryptography.com/ciphers/baconian-cipher/

  3. Singh, Simon. “The Code Book.” Doubleday, 1999.