The Voynich Ninja

Full Version: Engineering your own voynich
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12
Some hypothetical reconstruction of the encrypment process of the pangram: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG


Encryption Steps:
THE (sentence-start) → F (T-category initial) + ai (TH) + T (E) = FaiT

Next word must start with K (last bigram = iT).
QUICK → K (bigram rule) + zz (UIC) = Kzz

Next word starts with n (last bigram = zz).
BROWN → n + mn (BRO) + -nuy (null) = nmnuy

Next word starts with m (last bigram = uy).
FOX → m + aig (OX) = maig

Next word starts with q (last bigram = ig).
JUMPS → q + ar (UMPS) = qar

Next word starts with T (last bigram = ar).
OVER → T + iooiea (OVER) = Tiooiea

Next word starts with b (last bigram = ea).
THE (mid-sentence) → b + ar (HE) = bar

Next word starts with n (last bigram = ar).
LAZY → n + maei (AZY) = nmaei

Next word starts with T (last bigram = ei).
DOG → T + mz (OG) = Tmz

Final Ciphertext:
FaiT Kzz nmnuy maig qar Tiooiea bar nmaei Tmz
(03-04-2025, 08:51 AM)Scarecrow Wrote: You are not allowed to view links. Register or Login to view.As per new rules, all this with help of Claude and DeepSeek.

If you take your code and just remove "step 2", "step 3", "step 4" etc, and then run it, it will show exactly the same result for the test cases included. Which means that the only working part is a mapping of ciphertext words to plaintext words, which seems arbitrary and will work for almost any plaintext.

The following is the script you attached with everything except the basic dictionary mapping removed. It still passes all the test cases successfully.

Code:
from typing import Dict, Optional, List

class PangramDecoder:
    def __init__(self):
        self.last_bigram: Optional[str] = None

        # Complete cipher-to-plain mappings
        self.exact_matches = {
            # Core pangram
            "FaiT": "THE", "Kzz": "QUICK", "nmnuy": "BROWN",
            "maig": "FOX", "qar": "JUMPS", "Tiooiea": "OVER",
            "bar": "THE", "nmaei": "LAZY", "Tmz": "DOG",

            # Typography and extended vocabulary
            "Tiiiiz": "PANGRAM", "Tieir": "USES", "Kimb": "QUALITY",
            "mvg": "FONT", "Kaiin": "LETTERS", "Fvg": "THAT",
            "Tiiig": "STANDARD", "Kaiiea": "THE", "naean": "FONT",
            "Fmg": "SHOWS", "TaaT": "TYPICAL", "Faiyun": "FREQUENTLY",
            "Foonuy": "VISUALLY", "Tiavinn": "DISPLAYS", "TIeig": "TYPOGRAPHY",
            "Timyun": "DEMONSTRATE", "qooiea": "JUMPED", "Tiaeean": "STANDARD",
            "Teib": "THIS", "Kaaaouy": "OFTEN", "Fml": "A", "meaei": "AN",
            "TiiiT": "TYPOGRAPHY", "Tiiiig": "FREQUENTLY", "KaeiT": "CONTAINS",
            "KazT": "EXAMPLE", "Fiiiiz": "FREQUENTLY", "Fmyun": "SOMETIMES"
        }


    def decrypt_word(self, cipher_word: str) -> str:
        # Step 1: Check exact matches
        if cipher_word in self.exact_matches:
            self.last_bigram = cipher_word[-2:] if len(cipher_word) >= 2 else None
            return self.exact_matches[cipher_word]

    def decrypt_sentence(self, ciphertext: str) -> str:
        return " ".join(self.decrypt_word(word) for word in ciphertext.split())

# ======================
# Test Suite
# ======================
def run_tests():
    decoder = PangramDecoder()
    test_cases = [
        ("FaiT Kzz nmnuy maig qar Tiooiea bar nmaei Tmz",
        "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG"),
        ("Tiiiiz Tieir Kimb mvg Kaiin Fvg Tiiig",
        "PANGRAM USES QUALITY FONT LETTERS THAT STANDARD"),
        ("Kaiiea naean Fmg TaaT",
        "THE FONT SHOWS TYPICAL"),
        ("Faiyun Foonuy Tiavinn",
        "FREQUENTLY VISUALLY DISPLAYS"),
        ("TIeig Timyun qooiea Tiaeean",
        "TYPOGRAPHY DEMONSTRATE JUMPED STANDARD"),
        ("Fml meaei TiiiT KaeiT KazT",
        "A AN TYPOGRAPHY CONTAINS EXAMPLE"),
        ("Fiiiiz Fmyun Kaaaouy",
        "FREQUENTLY SOMETIMES OFTEN")
    ]

    for ciphertext, expected in test_cases:
        decrypted = decoder.decrypt_sentence(ciphertext)
        print(f"Ciphertext: {ciphertext}")
        print(f"Decrypted:  {decrypted}")
        print(f"Expected:  {expected}")
        print("✅ Pass" if decrypted == expected else "❌ Fail")
        print()

if __name__ == "__main__":
    run_tests()
Ok, not noticed. I just left the python code is for reference for people who do understand those things, I am not a reptile myself.
It might help, it might not but it should contain all the steps needed in codified way.
There has been many versions of it to test some hypothesis and grown to something as that, but I do not know how the Python really works.
(03-04-2025, 09:42 AM)Scarecrow Wrote: You are not allowed to view links. Register or Login to view.Ok, not noticed. I just left the python code is for reference for people who do understand those things, I am not a reptile myself.
It might help, it might not but it should contain all the steps needed in codified way.
There has been many versions of it to test some hypothesis and grown to something as that, but I do not know how the Python really works.

Ok, I understand. What is your opinion about this DeepSeek/ChatGPT solution, does it produce any interesting results?
Deepseek was an interesting. I haven't never used it before but it seemed to be very effective especially in pattern analysis.
I have paid Claude subscription so never or almost never use ChatGPT. 

Claude was good in some things but started to deviate from the reality more often than Deepseek, once Claude started to see philosophical dimensions in the method (Philosophical Implications, information is a living, transformable entity, Encryption becomes a revelatory process) so I had to bring it back to reality more often than Deepseek.
But both were needed and complemented each other.

I tried Gemini for some ideas but had troubles scanning the text, for example looped over and over and over and didn't stop, provided false positives more than the others.

Good aides for mathematically impaired, but neither of them would have done, but guided they are good tools, as long as you know that you are doing.
(03-04-2025, 10:29 AM)Scarecrow Wrote: You are not allowed to view links. Register or Login to view.Good aides for mathematically impaired, but neither of them would have done, but guided they are good tools, as long as you know that you are doing.

Did you try asking one LLM to scrutinize the result produced by the other? In my experience, two LLMs can produce interesting non-trivial results if one is tasked with finding flaws in the reasoning of the other.
(03-04-2025, 11:33 AM)oshfdk Wrote: You are not allowed to view links. Register or Login to view.
(03-04-2025, 10:29 AM)Scarecrow Wrote: You are not allowed to view links. Register or Login to view.Good aides for mathematically impaired, but neither of them would have done, but guided they are good tools, as long as you know that you are doing.

Did you try asking one LLM to scrutinize the result produced by the other? In my experience, two LLMs can produce interesting non-trivial results if one is tasked with finding flaws in the reasoning of the other.

Once in a while I asked the other to very, proof or analyze the confidence of the other. Most of the times they found something to say in each other's writings.
But it became somewhat useful verification and idea production tool.
(22-07-2021, 12:39 AM)Emma May Smith Wrote: You are not allowed to view links. Register or Login to view.A word like [naeyun] is perhaps [na-e-yun], and [Kimaei] is [Ki-m-aei]. But it feels as though the middle column is optional.

I should have followed this excellent advice instead of wasting time searching for solutions with optional (sometimes empty) 2nd and 3rd columns. This was mostly because of the last word: now I think it is missing a 3rd column because the ciphertext ends after the 2nd column, not because the 3rd column is optional.

A non-ambiguous 23-26-26 partition is possible, still looking for more reduced 2nd and 3rd columns.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12