not so easy binary decode

problem

Little Timmy always admired hackers so he made a program to encrypt his lucky NUMBER using binary. However, he forgot to make the decryption program and now he can’t decode his lucky NUMBER. Maybe you can help him? You should submit ictf as the flag

s = input("Enter your secret: ")
res = ''.join(format(ord(i), 'b') for i in s)
print("Ciphertext: " + res)

output:

110010111001110011110011110111111001110000110100110001110101110111110011110001110001111000110000110100110101111001110100110010110001110111111000110000110110110010110100110101110101111000111001110001110001110001110101110110111000110011111001110011111001110110110000110101110100110010111001110000110110110011110001110010110110110010110101110000110011110111110100110110110011110010111000110101110100

solution

we can see that because of the format function, it removes the leading zeros of each character’s binary representation

01010101 goes to 1010101. etc

what we can do is that because we know it’s a number, we can use the fact that all ASCII numbers representation in binary contains two trailing zeros to our advantage

we don’t even need to use python for this one. we can just use text-format-wizard

so, for every 6 bits, we can add two zeros before to get

00110010
00111001
00110011
00110011
00110111
00111001
00110000
00110100
00110001
00110101
00110111
00110011
00110001
00110001
00111000
00110000
00110100
00110101
00111001
00110100
00110010
00110001
00110111
00111000
00110000
00110110
00110010
00110100
00110101
00110101
00111000
00111001
00110001
00110001
00110001
00110101
00110110
00111000
00110011
00111001
00110011
00111001
00110110
00110000
00110101
00110100
00110010
00111001
00110000
00110110
00110011
00110001
00110010
00110110
00110010
00110101
00110000
00110011
00110111
00110100
00110110
00110011
00110010
00111000
00110101
00110100

then we decode to get the flag which is ictf{293379041573118045942178062455891115683939605429063126250374632854}

here is a code golf solution for this:

n="110010111001110011110011110111111001110000110100110001110101110111110011110001110001111000110000110100110101111001110100110010110001110111111000110000110110110010110100110101110101111000111001110001110001110001110101110110111000110011111001110011111001110110110000110101110100110010111001110000110110110011110001110010110110110010110101110000110011110111110100110110110011110010111000110101110100"
print("".join(chr(int(n[_:_+6],2))for _ in range(0,396,6)))

i was also wondering that if other characters were allowed, you could brute force different strings

allowed = "0123456789abcdefghijklmnopqrstuvwxyz"

n = "110010111001110011110011110111111001110000110100110001110101110111110011110001110001111000110000110100110101111001110100110010110001110111111000110000110110110010110100110101110101111000111001110001110001110001110101110110111000110011111001110011111001110110110000110101110100110010111001110000110110110011110001110010110110110010110101110000110011110111110100110110110011110010111000110101110100"


def reduce(n_str: str) -> list[str]:
    if len(n_str) == 0:
        return ['']
    possible = []
    for index in range(1, len(n_str)+1):
        substr = n_str[:index]
        if int(substr, 2) >= 256:
            break
        if chr(int(substr, 2)) in allowed:
            for _ in reduce(n_str[index:]):
                possible.append(chr(int(substr, 2)) + _)
    return possible


print(reduce(n))