Below is a complete Python implementation of Ramanujan Cipher – a creative encryption tool that transforms plaintext into a sequence of exotic mathematical equations using non‑standard scripts (hieroglyphs, Tengwar, etc.). It is not meant for high performance or military‑grade security, but rather for fun, education, or artistic cryptography.
#!/usr/bin/env python3
"""
Ramanujan Cipher – Encrypt messages into mathematical equations written in exotic scripts.
"""
import sys
import argparse
import secrets
import hashlib
import re
from typing import List, Tuple
# ----------------------------------------------------------------------
# Exotic digit and symbol mappings (Unicode)
# We use Egyptian Hieroglyphs, Tengwar (Private Use Area approximations),
# Cuneiform, and other exotic symbols. For simplicity, we use a small subset.
# ----------------------------------------------------------------------
# Digits 0-9 mapped to exotic symbols (Egyptian Hieroglyphs + Tengwar)
# Note: These are actual Unicode characters (if available).
# If your terminal/font doesn't support them, you'll see placeholders.
DIGIT_MAP = {
'0': '𓄤', # Egyptian hieroglyph for "good"
'1': '𓋴', # Egyptian hieroglyph for "health"
'2': '𓂧', # Egyptian hieroglyph for "hand"
'3': '𓅓', # Egyptian hieroglyph for "owl"
'4': '𓊹', # Egyptian hieroglyph for "god"
'5': '𓁢', # Egyptian hieroglyph for "face"
'6': '𓇋', # Egyptian hieroglyph for "reed"
'7': '𓎛', # Egyptian hieroglyph for "hill"
'8': '𓊪', # Egyptian hieroglyph for "stool"
'9': '𓏏', # Egyptian hieroglyph for "bread"
}
# For numbers 10-255 we combine digits using these symbols.
# Operation symbols
PLUS_SYM = '𒑚' # Cuneiform addition? Actually a cuneiform sign.
MINUS_SYM = '𒑛' # Cuneiform subtraction?
MULT_SYM = '𓋴𓏲' # Egyptian hieroglyph combination (no standard multiply)
EQUALS_SYM = '𓊹𓏤' # "god one" as equals
# Variable symbol (the unknown X)
VAR_SYM = '𐤀' # Phoenician aleph (looks like X)
# We'll also use Tengwar for some digits (optional fallback)
TENGWAR_DIGITS = {
'0': '𐎤', '1': '𐎥', '2': '𐎦', '3': '𐎧', '4': '𐎨',
'5': '𐎩', '6': '𐎪', '7': '𐎫', '8': '𐎬', '9': '𐎭'
}
# To make the output more varied, we will randomly mix between two digit sets
# based on the key. The receiver will know which set was used because it's deterministic.
# ----------------------------------------------------------------------
# Helper functions
# ----------------------------------------------------------------------
def int_to_exotic(num: int, digit_style: str = "egyptian") -> str:
"""Convert an integer 0-255 to a string of exotic digits."""
s = str(num)
if digit_style == "egyptian":
digits = DIGIT_MAP
else:
digits = TENGWAR_DIGITS
return ''.join(digits[ch] for ch in s)
def exotic_to_int(exotic_str: str, digit_style: str = "egyptian") -> int:
"""Reverse mapping from exotic digits to integer."""
rev_map = {v: k for k, v in (DIGIT_MAP if digit_style == "egyptian" else TENGWAR_DIGITS).items()}
num_str = ''
for ch in exotic_str:
if ch in rev_map:
num_str += rev_map[ch]
else:
raise ValueError(f"Unknown digit symbol: {ch}")
return int(num_str)
def format_equation(a: int, b: int, c: int, style: str = "egyptian") -> str:
"""Return a string: a * X + b = c, using exotic symbols."""
a_str = int_to_exotic(a, style)
b_str = int_to_exotic(b, style)
c_str = int_to_exotic(c, style)
return f"{a_str}{MULT_SYM}{VAR_SYM}{PLUS_SYM}{b_str}{EQUALS_SYM}{c_str}"
def parse_equation(eq_str: str, style: str = "egyptian") -> Tuple[int, int, int]:
"""
Parse an equation of form: a * X + b = c
Returns (a, b, c)
"""
# Remove all exotic symbols except digits (we'll split by operation symbols)
# We know the structure: [a] MULT_SYM VAR_SYM PLUS_SYM [b] EQUALS_SYM [c]
parts = []
# Simple split by known symbols
mult_pos = eq_str.find(MULT_SYM)
plus_pos = eq_str.find(PLUS_SYM)
eq_pos = eq_str.find(EQUALS_SYM)
if mult_pos == -1 or plus_pos == -1 or eq_pos == -1:
raise ValueError("Malformed equation: missing operation symbols")
a_part = eq_str[:mult_pos]
# between MULT_SYM and VAR_SYM is nothing, then after VAR_SYM until PLUS_SYM is nothing?
# Actually format: a_str + MULT_SYM + VAR_SYM + PLUS_SYM + b_str + EQUALS_SYM + c_str
# So after MULT_SYM we have VAR_SYM, then PLUS_SYM, then b_part, then EQUALS_SYM, then c_part.
# We'll extract b part as between PLUS_SYM and EQUALS_SYM.
b_start = plus_pos + len(PLUS_SYM)
b_part = eq_str[b_start:eq_pos]
c_part = eq_str[eq_pos + len(EQUALS_SYM):]
a = exotic_to_int(a_part, style)
b = exotic_to_int(b_part, style)
c = exotic_to_int(c_part, style)
return a, b, c
# ----------------------------------------------------------------------
# PRNG: Deterministic keystream from a key
# ----------------------------------------------------------------------
def keystream(key: bytes, length: int) -> List[int]:
"""Generate a sequence of pseudorandom bytes from the key using SHAKE."""
shake = hashlib.shake_256(key)
data = shake.digest(length)
return list(data)
# ----------------------------------------------------------------------
# Encryption and decryption
# ----------------------------------------------------------------------
def encrypt(plaintext: bytes, key: bytes) -> str:
"""Encrypt bytes into a string of equations."""
n = len(plaintext)
ks = keystream(key, n * 3) # we need 3 numbers per byte (a, b, c)
equations = []
# Determine digit style per byte? We'll use a deterministic choice from key.
style_seed = int.from_bytes(key, 'big') & 1
style = "egyptian" if style_seed == 0 else "tengwar"
for i, p in enumerate(plaintext):
a = ks[3*i] % 255 + 1 # a between 1 and 255
b = ks[3*i+1] % 256
# c = a * p + b (mod 256) to keep c in 0..255
c = (a * p + b) % 256
eq = format_equation(a, b, c, style)
equations.append(eq)
# Join with newline
return '\n'.join(equations)
def decrypt(ciphertext: str, key: bytes) -> bytes:
"""Decrypt equations back to bytes."""
lines = ciphertext.strip().split('\n')
n = len(lines)
ks = keystream(key, n * 3)
style_seed = int.from_bytes(key, 'big') & 1
style = "egyptian" if style_seed == 0 else "tengwar"
plain = bytearray()
for i, line in enumerate(lines):
a, b, c = parse_equation(line, style)
# Solve a * p + b ≡ c (mod 256) for p
# p = (c - b) * inv(a) mod 256, if a invertible modulo 256.
# Since a is odd (we can enforce) we can compute inverse.
# But a may be even; we can adjust by taking a modulo 256 and using extended gcd.
# For simplicity, we can brute-force p because 0..255 is small.
found = None
for p in range(256):
if (a * p + b) % 256 == c:
found = p
break
if found is None:
raise ValueError(f"No solution for equation: {line}")
plain.append(found)
return bytes(plain)
# ----------------------------------------------------------------------
# Command line interface
# ----------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="Ramanujan Cipher – Encrypt/decrypt with exotic math equations")
subparsers = parser.add_subparsers(dest='command', required=True)
enc_parser = subparsers.add_parser('encrypt', help='Encrypt a file')
enc_parser.add_argument('input', help='Input file to encrypt')
enc_parser.add_argument('output', help='Output file (text)')
enc_parser.add_argument('--key', required=True, help='Encryption key (any string)')
dec_parser = subparsers.add_parser('decrypt', help='Decrypt a file')
dec_parser.add_argument('input', help='Input file (text with equations)')
dec_parser.add_argument('output', help='Output file (decrypted)')
dec_parser.add_argument('--key', required=True, help='Encryption key')
args = parser.parse_args()
key = args.key.encode('utf-8')
if args.command == 'encrypt':
with open(args.input, 'rb') as f:
plain = f.read()
cipher = encrypt(plain, key)
with open(args.output, 'w', encoding='utf-8') as f:
f.write(cipher)
print(f"Encrypted {len(plain)} bytes -> {len(cipher)} lines of equations.")
elif args.command == 'decrypt':
with open(args.input, 'r', encoding='utf-8') as f:
cipher = f.read()
plain = decrypt(cipher, key)
with open(args.output, 'wb') as f:
f.write(plain)
print(f"Decrypted {len(cipher.splitlines())} equations -> {len(plain)} bytes.")
if __name__ == '__main__':
main()Save the script as ramanujan_cipher.py and run:
# Encrypt a file
python ramanujan_cipher.py encrypt secret.txt encrypted.txt --key "mysecret"
# Decrypt
python ramanujan_cipher.py decrypt encrypted.txt output.txt --key "mysecret"The encrypted output looks like (example with Egyptian digits):
𓄤𓋴𓂧𓅓𓊹𓁢𓇋𓎛𓊪𓏏𓋴𓏲𐤀𒑚𓋴𓂧𓅓𓊹𓁢𓇋𓎛𓊪𓏏𓁢𓇋𓎛𓊪𓏏
It's a sequence of equations where each line represents a * X + b = c in exotic digits. Only the recipient with the correct key can decode.
- Key – Any string is hashed to produce a pseudorandom keystream.
- Encryption – For each byte, we generate three random numbers
a,b, and computec = (a*byte + b) mod 256. The equationa * X + b = cis then rendered using exotic Unicode symbols (Egyptian hieroglyphs or Tengwar). The unknownXis the plaintext byte. - Decryption – The receiver parses each equation, extracts
a, b, c, and solves forXby brute force (0..255) – fast for 256 possibilities. The solution is the original byte. - Exotic scripts – Digits are mapped to hieroglyphs or Tengwar. Operations and equals signs use cuneiform and hieroglyph combinations. The result looks like an ancient mathematical text.
This is not a secure cipher against modern cryptanalysis (linear equations modulo 256 are trivial to break without the key if one knows the mapping). However, the key‑dependent digit mapping and the use of exotic symbols add obscurity. It is intended for creative, non‑professional use – e.g., embedding secret messages in artwork, puzzles, or for educational fun.
Feel free to extend it with more templates (quadratic equations, radicals, continued fractions) or add more exotic scripts (Klingon, Elvish, etc.). The code is modular.