def decrypt(ct, k):
    # pad the ciphertext using PKCS#7 if needed
    if len(ct) % len(k) > 0:
        ct = pkcs7_padding(ct, len(ct) + (len(k) - len(ct) % len(k)))
    assert len(ct) % len(k) == 0

    pt = [0 for i in range(len(ct))]

    for i in range(len(ct), len(k), -len(k)):
        x = aes_ecb.decrypt(ct[i - len(k) : i], k)
        pt[i - len(k) : i] = fxd_xor.fxd_xor(x, ct[i - 2 * len(k) : i - len(k)])

    x = aes_ecb.decrypt(ct[0 : len(k)], k)
    pt[0 : len(k)] = fxd_xor.fxd_xor(x, [0 for x in range(len(k))])  # using the IV
    return pt
def hmming_dist(s, t):
    assert len(s) == len(t)
    bp = int(binascii.hexlify(bytes(fxd_xor(s, t))), 16)

    def f(bp, cnt=0):
        if bp == 0: return cnt
        if bp & 1 != 0: return f(bp >> 1, cnt +1)
        return f(bp >> 1, cnt)
    return f(bp)
def crk_1bxor(c, tl=0.98):
    lst = []
    for b in range(0, 256):
        k = [b] * len(c)
        _p = fxd_xor(c, k)
        p = list(map(lambda x: x+32 if x in range(65,91) else x, _p))
        o = dict(zip(range(97,123), [0]*26))
        ln = 0
        for x in p:
            if x in o:
                o[x] += 1
                ln += 1
            elif x in b' \n\r\t\'':
                ln += 1
        if ln/len(p) < tl: continue
        e = dict(map(lambda x: (x[0], x[1]/100*ln), en.items()))
        lst.append((chi_sqrd(o, e), _p, k))
    lst.sort(key=lambda x: x[00])
    return lst
def rpting_xor(s, k):
    while len(k) < len(s): k += k
    k = k[:len(s)]
    return fxd_xor(s, k)