A Python package for solving simple substitution ciphers using pattern matching and constraint propagation.
pip install cryptogramsfrom cryptograms import solve_cryptogram, encrypt_cryptogram
# Solve a cipher
solution = solve_cryptogram("Ybvo jtweg cl rn nwnvrmhmhz rn xlremvb - ntylvmyln ldlh ytxl nt")
print(solution.plaintext) # Myth could be as sustaining as reality - sometimes even more so
print(solution.confidence) # 0.70
# Encrypt plaintext (useful for generating puzzles)
ciphertext = encrypt_cryptogram("Hello world")
print(ciphertext) # e.g. Ebiil tloia# Decrypt — accepts a string or a file path
cryptograms decrypt "Ebiil tloia"
cryptograms decrypt puzzle.txt
# Encrypt
cryptograms encrypt "Hello world"
cryptograms encrypt "Hello world" --seed 42 # reproducible outputThe solver uses word-pattern matching and constraint propagation rather than frequency analysis:
- Each cipher word is encoded as a numeric pattern —
"KHOOR"→"12334" - Candidate plaintext words are looked up by pattern from a ~200k-word frequency-weighted dictionary
LetterConstraintstracks which plaintext letters each cipher letter can still map to, and propagates locks globally when a mapping is confirmed- Candidates and constraints are narrowed iteratively until every cipher word resolves to one plaintext word
- When stuck, the solver uses NLTK Brown corpus bigram/trigram frequencies to pick the most contextually likely candidate and continues
Word frequencies from wordfreq. Bigram and trigram context from the NLTK Brown corpus, downloaded automatically on first use.
A self-hostable web interface is available in the repository. Run it with:
pip install cryptograms[web]
uvicorn cryptograms.api:app