DEV Community

Willy Vaessen
Willy Vaessen

Posted on

TryHackMe | Cipher's Secret Message | WillyVaessen

➡️ by @willyvaessen
📅 Written: 6 July 2025

Platform: TryHackMe
Room: Cipher's Secret Message

Introduction

One of the Ciphers' secret messages was recovered from an old system alongside the encryption algorithm, but we are unable to decode it.

Order: Can you help void to decode the message?

Message : a_up4qr_kaiaf0_bujktaz_qm_su4ux_cpbq_ETZ_rhrudm

Encryption algorithm :

from secret import FLAG

def enc(plaintext):
    return "".join(
        chr((ord(c) - (base := ord('A') if c.isupper() else ord('a')) + i) % 26 + base) 
        if c.isalpha() else c
        for i, c in enumerate(plaintext)
    )

with open("message.txt", "w") as f:
    f.write(enc(FLAG))
Enter fullscreen mode Exit fullscreen mode

Note: Wrap the decoded message within the flag format THM{}

Solving the puzzle

Step 1: Understanding the encoding.

The code above basically does the following:

The function takes your original string and iterates over every position in the string.
For every position it checks whether the character is in the alphabet (a-z or A-Z) or not. In case the character is not alphabet (.isalpha() == False), it gets appended to the new (encoded) string as is, but if it IS in fact alphabetic (.isalpha() == True) it is shifted based on the index (i), starting from the base depending on uppercase or lowercase. The resulting (encoded) string is then returned by the function.

Step 2: Rewriting the algorithm

To better understand how this algorithm works, I decided to copy the code into PyCharm first and run it with a simple string that I knew: abcde.

The import line can safely be ignored and commented out. Even though there is a package called secret I noticed that there was no such thing as FLAG in that package. I declared a variable FLAG = "abcde" and ran the code. The resulting message.txt file contains the encoded string acegi so it quickly became clear to me that the character is shifted by its position in the string.

Now to unravel the algorithm.

To better understand what happens behind the scenes, I rewrote the existing enc(plaintext) function into something more readable:

def encode(plaintext):  
    encoded_string = ""  
    replacement_char = ""  
    for i, c in enumerate(plaintext):  
        if c.isalpha():  
            if c.isupper():  
                base=ord('A')  
            else:  
                base=ord('a')  
            replacement_char = chr(((ord(c) - base + i) % 26) + base)  
        else:  
            replacement_char = c  
        encoded_string += replacement_char  
    print(f"Replacement string is {encoded_string}")  
    return encoded_string
Enter fullscreen mode Exit fullscreen mode
FLAG = "abcde" 
print(encode(FLAG))  # Output: acegi
Enter fullscreen mode Exit fullscreen mode

Step 3: Decoding the message

Once I understood what the algorithm did exactly, it became a lot easier to see that the decoding algorithm was a matter of simply inverting one + into a -

def decode(encoded_text):  
    decoded_string = ""  
    replacement_char = ""  
    for i, c in enumerate(encoded_text):  
        if c.isalpha():  
            if c.isupper():  
                base=ord('A')  
            else:  
                base=ord('a')  
            replacement_char = chr(((ord(c) - base - i) % 26) + base)  
        else:  
            replacement_char = c  
        decoded_string += replacement_char  
    print(f"Replacement string is {decoded_string}")  
    return decoded_string
Enter fullscreen mode Exit fullscreen mode

Run that with the encoded message provided in the puzzle, wrap the result in the THM{...} format, and voilà:

Congratulations on completing Cipher's Secret Message!!! 🎉

Lessons learned

  • To me it really helped understand the code by rewriting it. I've experienced this before in cases where 'Lambda functions' were used. Writing shorter code might be good performance-wise, but it makes understanding the code a lot more difficult, at least in my case.
  • Writing a decoding algorithm can be surprisingly easy, once you understand the encoding process.

Top comments (0)