def decipher_hill(msg, key, symbols=None):
 assert key.is_square
 (msg, _, A) = _prep(msg, '', symbols)
 map = {c: i for (i, c) in enumerate(A)}
 C = [map[c] for c in msg]
 N = len(A)
 k = key.cols
 n = len(C)
 (m, r) = divmod(n, k)
 if r:
  C = (C + ([0] * (k - r)))
  m += 1
 key_inv = key.inv_mod(N)
 rv = ''.join([A[(p % N)] for j in range(m) for p in list((key_inv * Matrix(k, 1, [C[i] for i in range((k * j), (k * (j + 1)))])))])
 return rv

def decipher_hill ( msg , key , symbols = None ) : assert key . is_square ( msg , _ , A ) = _prep ( msg , '' , symbols ) map = { c : i for ( i , c ) in enumerate ( A ) } C = [ map [ c ] for c in msg ] N = len ( A ) k = key . cols n = len ( C ) ( m , r ) = divmod ( n , k ) if r : C = ( C + ( [ 0 ] * ( k - r ) ) ) m += 1 key_inv = key . inv_mod ( N ) rv = '' . join ( [ A [ ( p % N ) ] for j in range ( m ) for p in list ( ( key_inv * Matrix ( k , 1 , [ C [ i ] for i in range ( ( k * j ) , ( k * ( j + 1 ) ) ) ] ) ) ) ] ) return rv
deciphering is the same as enciphering but using the inverse of the key matrix .