import string
from Crypto.Util.number import long_to_bytes
LOWERCASE_OFFSET = ord("a")
ALPHABET = string.ascii_lowercase[:16]

def b16_encode(plain):
    enc = ""
    for c in plain:
        binary = "{0:08b}".format(ord(c))
        #turns it into bits
        enc += ALPHABET[int(binary[:4], 2)]
        #first 4 bits into binary, then takes the first 16 chars
        enc += ALPHABET[int(binary[4:], 2)]
        #last 4 bits into binary, then takes the first 16 chars
    return enc

def shift(c, k):
    t1 = ord(c) - LOWERCASE_OFFSET #position
    t2 = ord(k) - LOWERCASE_OFFSET #position
    return ALPHABET[(t1 + t2) % len(ALPHABET)] #position of t1 + t2, caesar
"""
flag = "redacted"
key = "redacted"
assert all([k in ALPHABET for k in key])
assert len(key) == 1
#key is a letter, hence brute forceable

b16 = b16_encode(flag)
enc = ""
for i, c in enumerate(b16):
    enc += shift(c, key[i % len(key)])
print(enc)

enc = ""
"""
def deshift(c, key):
    t1 = ord(c) - ord('a') #we dont know
    t2 = ord(key) - ord('a')
    #to find original just do
    return ALPHABET[(t1-t2)%len(ALPHABET)]

for i in range(26):
    #guess the key
    enc = "fegdeogdgecoeocgcgchcfcffccfca"
    key = chr(i+ord('a'))
    temp = ""
    for j,c in enumerate(enc):
        temp += deshift(c, key)
    print(temp)
    pt = ""
    for k in range(0, len(temp), 2):
        print(ALPHABET.index(temp[k]), ALPHABET.index(temp[k+1]))
        a = ALPHABET.index(temp[k])
        b = ALPHABET.index(temp[k+1])
        c = a << 4 | b
        pt += chr(c)
    print(pt)
    