Pipher - Piano Cipher

Back in my school days, we were required to pick a "Leisure Time Activity" as part of the curriculum. Four days a week, we had to attend those classes and learn whatever we chose. I opted for the piano—or more specifically, the keyboard.

From junior school through high school, I gradually improved. Over time, I moved beyond simply memorizing notes and developed the ability to judge sounds and map notes instinctively, even when hearing a song for the first time. When I discovered this skill, it felt incredible.

But this joy was short-lived. My musical journey ended when I entered high school, as academics took precedence. Later, I pursued my bachelor's degree far from home, leaving my piano behind. It's a decision I've often regretted. Now, all I have are fond, fleeting memories of those starry-eyed days as a kid.

In honor of that time, I've created a cipher called the Pipher. There's a bug in it, though—every 6th character of the plaintext leaks. So, yeah, it’s still a work in progress.

Attachment: File named cipher.txt containing:

Ciphertext - DC# DD# DF DD# EC '70' G#B CE F#C FC# C#C# '104' C#A FC# F#A# C#A C#A '108' CF AF# C#C FC# CE '102' FC# C#A# FC# GA# CE '112' FC# C#B C#C# C#A# GC '125'

Solution

Having only rudimentary knowledge about music theory, I just assumed that notes represented numbers and started from there,

After a bit of googling around, i stumbled upon an image explaining piano scales

From here, i just wrote a script which mapped the above cipher text into integers based on this and then to chars, strung them together and that was that:

#!/usr/bin/env python3

input = "DC# DD# DF DD# EC '70' G#B CE F#C FC# C#C# '104' C#A FC# F#A# C#A C#A '108' CF AF# C#C FC# CE '102' FC# C#A# FC# GA# CE '112' FC# C#B C#C# C#A# GC '125'"

map = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"]

output = []

print(len(input.split()))

for char in input.split():
    current = char
    if current.startswith("'"):
        current = current.strip("'")
        output.append(int(current))
        continue
    for i in range(len(map) - 1, -1, -1):
        if current.startswith(map[i]):
            output.append(i + 1)
            current = current[len(map[i]) :]
            break

    for i in range(len(map) - 1, -1, -1):
        if current.startswith(map[i]):
            output[len(output) - 1] = output[len(output) - 1] * 10 + i + 1
            break

print(len(output))

print("".join([chr(x) for x in output]))

Running this gave the output of:

36
36
ACECTF{0h_7h3_f33l16_0f_4_p0p_574r}

But there was a problem, the site didn't accept this flag, i ended up one of the organizer via discord, and he told me there was a typo.

I figured, that 0h_7h3_f33l16_0f_4_p0p_574r is probably oh the feelig of a pop star

i manually added an n in f33l1n6 and the site accepted it, idk if this was how it was supposed to be solved, but hey, it worked

ACECTF{0h_7h3_f33l1n6_0f_4_p0p_574r}