team-logo
Published on

Junior.Crypt.2025 CTF - Crypto - More than Ascii85

Authors
More than Ascii85

flag: grodno{the_hardest_part_of_encoding_and_decoding_is_padding}

The challenge description suggests that the encoding is somewhat similar to Ascii85 (also called Base85). The standard alphabet for Base85 is !-u.

Based on the analysis of the encoded text:

enc = ";Ibge=6Sb+;_TAM9sZoF>P'Vo9s[Bn=Le:4=5L7];wD_89s:NZ:]OHr:]p.j9Dj!D=c>7%;wD_V"

codes = {ord(e) for e in enc}
print(f"{min(codes) = }") # 33
print(f"{max(codes) = }") # 119

we could assume that it's Base87 (alphabet !-w). Decoding doesn't return anything meaningful, so we keep increasing the base a little further. Soon enough, we find out that the text was encoded using Base90 (alphabet !-z).

ALPHA = r"""!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz"""
BASE = 90
assert len(ALPHA) == BASE

def decode(encoded):
    assert len(encoded) % 5 == 0

    c_to_v = {ch: i for i, ch in enumerate(ALPHA)}

    decoded = bytearray()
    for i in range(0, len(encoded), 5):
        chunk = encoded[i : i + 5]
        num = 0
        for ch in chunk:
            num = num * BASE + c_to_v[ch]
        decoded.extend(num.to_bytes(4, byteorder="big"))

    return bytes(decoded)

enc = ";Ibge=6Sb+;_TAM9sZoF>P'Vo9s[Bn=Le:4=5L7];wD_89s:NZ:]OHr:]p.j9Dj!D=c>7%;wD_V"
print(decode(enc))