21-07-2025, 11:30 AM
I asked in the You are not allowed to view links. Register or Login to view. if a made up chain cipher is easy to decrypt. Now I have written a Python script that decrypts a given Voynich word using the same method. The result is then mapped according to frequency analysis (EVA > Latin). Admittedly, this is a rather rudimentary approach, I am primarily interested in decoding with MOD 23. The method is simple enough to be considered and also much more effective than a simple substitution. It could be implemented practically with a letter disk (like Alberti disk).
Here is the python - script and a list of possibly unabbreviated words ( Stolfi ):
chesokchoteody [f68r1, outer ring, near the bottom]
oepchksheey [f93r, top line, but looks like half of a Neal key]
qoekeeykeody [f105r, which I’d note is possibly the original first page of Q20A]
soefchocphy [f102r2, right edge, but right on the fold, very hard to read]
ykcheolchcthy [f68v3, first word of second line]
shdykairalam [f106v, last word of a line]
shetcheodchs [f43v, first word of a line]
A side note:
"shetcheodchs" was converted to "LDYIFEYNDUEO" using the method described. ChatGPT hallucinates "Fide leo, deus unde" from it by rearranging, omitting and adding letters, which means "Trust the lion - God is its origin". This is remarkable because the plants on You are not allowed to view links. Register or Login to view. ( sun and moon ) could very well be connected with the lion according to alchemical interpretation. So you could easily fall for ChatGPT if you believe what you want to believe
Here is the python - script and a list of possibly unabbreviated words ( Stolfi ):
chesokchoteody [f68r1, outer ring, near the bottom]
oepchksheey [f93r, top line, but looks like half of a Neal key]
qoekeeykeody [f105r, which I’d note is possibly the original first page of Q20A]
soefchocphy [f102r2, right edge, but right on the fold, very hard to read]
ykcheolchcthy [f68v3, first word of second line]
shdykairalam [f106v, last word of a line]
shetcheodchs [f43v, first word of a line]
Code:
# Reduced alphabet: No J, U, W
alphabet = list("ABCDEFGHIKLMNOPQRSTVXYZ") # 23 letters
def char_to_pos(c):
return alphabet.index(c.upper()) + 1
def pos_to_char(p):
p = (p - 1) % len(alphabet) + 1
return alphabet[p - 1]
def chain_decrypt_verbose(ciphertext):
ciphertext = ciphertext.upper()
decrypted = ""
table = []
prev_cipher_pos = 0
for i, c in enumerate(ciphertext, start=1):
if c not in alphabet:
decrypted += c
table.append([i, c]) # Nur zwei Spalten für Nicht-Buchstaben
continue
cipher_pos = char_to_pos(c)
plain_pos = (cipher_pos - prev_cipher_pos) % len(alphabet)
if plain_pos == 0:
plain_pos = len(alphabet)
plain_char = pos_to_char(plain_pos)
decrypted += plain_char
table.append([
i,
c,
cipher_pos,
plain_char,
plain_pos,
prev_cipher_pos,
f"({cipher_pos} - {prev_cipher_pos}) mod {len(alphabet)} = {plain_pos}"
])
prev_cipher_pos = cipher_pos
return decrypted, table
def print_table(table):
print("\nDecryption Table:")
print("-" * 90)
print(f"{'i':>3} | {'Cipher':^9} | {'cᵢ':^4} | {'Plain':^9} | {'pᵢ':^4} | {'cᵢ₋₁':^6} | {'Computation':<30}")
print("-" * 90)
for row in table:
if len(row) == 7:
i, cchar, cpos, pchar, ppos, cprev, calc = row
print(f"{i:>3} | {cchar:^9} | {cpos:^4} | {pchar:^9} | {ppos:^4} | {cprev:^6} | {calc:<30}")
elif len(row) == 2:
i, cchar = row
print(f"{i:>3} | {cchar:^9} | {'-':^4} | {'-':^9} | {'-':^4} | {'-':^6} | {'(not a letter)':<30}")
print("-" * 90)
def apply_fixed_substitution(text, from_list, to_list):
mapping = dict(zip(from_list, to_list))
substituted = ''.join(mapping.get(c, c) for c in text)
return substituted, mapping
if __name__ == "__main__":
text = input("? Enter ciphertext to decrypt (only letters A–Z, excluding J, U, W): ")
decrypted, table = chain_decrypt_verbose(text)
print(f"\n? Decrypted text: {decrypted}")
print_table(table)
# Substitution: Voynich → Latein
voynich_order = list("OEHYACDIKLRSTNQPMFGXBVZ")
latin_order = list("IEAUTSRNOMCLPDBQGVFHXYZ")
substituted, mapping = apply_fixed_substitution(decrypted, voynich_order, latin_order)
print("\n? Substituted (Voynich → Latin):")
print(substituted)
print("\n?️ Substitution Map:")
for voy, lat in mapping.items():
print(f" {voy} → {lat}")
A side note:
"shetcheodchs" was converted to "LDYIFEYNDUEO" using the method described. ChatGPT hallucinates "Fide leo, deus unde" from it by rearranging, omitting and adding letters, which means "Trust the lion - God is its origin". This is remarkable because the plants on You are not allowed to view links. Register or Login to view. ( sun and moon ) could very well be connected with the lion according to alchemical interpretation. So you could easily fall for ChatGPT if you believe what you want to believe
