Basically, for every 12-bit string, the first 8 bits is equivalent to the ASCII code. The remaining 4 bits are deterministically calculated from the ASCII code of the original character. But, one random bit of the 12 is flipped.
To solve this, we can calculate the 4-bit codes of every possible character. Some of them will repeat since there are only 16 possible 4-bit codes and there are 128 ASCII characters. Therefore, for every 4-bit code, we will make an array of the possible ASCII characters.
Then, for every 12-bit string, we’ll take the first 8 bits and create a set of all the possible corresponding ASCII characters, flipping one of the bits each time. We’ll also take the last 4 bits and match it to the corresponding possible ASCII character set. We will then find the intersection of these two sets.
If a bit was flipped in the first 8 bits, the intersection of the 2 sets should produce the correct ASCII character. If a bit was flipped in the last 4 bits instead, the intersection of the 2 sets will be empty, in which case the 8 bits correspond to the correct ASCII character.
a = [] b = [] for i inrange(len(ct)//12): a.append(ct[i*12:i*12+8]) b.append(ct[i*12+8:i*12+12])
charset = '' for i inrange(32, 128): charset += chr(i)
res = encrypt(charset)
d = dict() for i inrange(len(res)//12): s = res[i*12+8:i*12+12] if s notin d.keys(): d[s] = list() d[s].append(charset[i])
flag = '' for i inrange(len(a)): x = int(a[i], 2) s = set() for j inrange(8): s.add(chr(x ^ 1<<j)) y = b[i] inter = s.intersection(set(d[y])) flag += str(inter)[2] iflen(inter) > 0elsechr(x)