def div(a, b, mod): inv_b, gcd = extended_gcd(b, mod) if gcd == 1: raise ValueError() return mul(a, inv_b, mod)
def chinese_remainder_theorem(ais, nis): """Construct a solution to the chinese remainder theorem Given a list of a[i]'s and n[i]'s constructs an x such that x = a[i] (mod n[i]) for all i """ N = reduce(lambda x, y: x*y, nis, 1) ei = [extended_gcd(ni, N/ni)[1] * (N/ni) for ni in nis] return sum([x[0]*x[1] for x in zip(ais, ei)]) % N
def decrypt(cipher, key_a, key_b): inverse, am_gcd = extended_gcd(key_a, 26) assert(am_gcd == 1) message = "" for c in cipher: if c.isalpha(): x = ord(c.upper()) - ord("A") y = ((x - key_b) * inverse) % 26 message += chr(y + ord("A")) else: message += c return message