Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Clear category for Playfair Cipher by gyahun_dash
import itertools as it, re, string
order = string.ascii_lowercase + string.digits
class Table:
def __init__(self, key):
prior = sorted(set(key), key = key.index)
self.table = prior + [c for c in order if c not in prior]
def index(self, c):
return divmod(self.table.index(c), 6)
def __getitem__(self, cell):
return self.table[(cell[0] % 6) * 6 + (cell[1] % 6)]
def shift(codec: '1: encoding, -1: decoding'):
def _trans(i, j):
if i[0] == j[0]: return (i[0], i[1] + codec), (j[0], j[1] + codec)
if i[1] == j[1]: return (i[0] + codec, i[1]), (j[0] + codec, j[1])
return (i[0], j[1]), (j[0], i[1])
return _trans
def trans(splits, key, codec: '1: encoding, -1: decoding'):
table = Table(key)
trs = it.starmap(shift(codec), (map(table.index, pair) for pair in splits))
return ''.join(table[cell] for cell in it.chain.from_iterable(trs))
def encode(message, key):
form = ''.join(c for c in message.lower() if c in order)
divs = [g1 or g2 for g1, g2 in re.findall(r'(.)(?=\1|$)|(..)', form)]
if len(divs[-1]) == 1: divs[-1] += 'z'
fill = lambda s: s + 'z' if s == 'x' else s + 'x' if len(s) == 1 else s
return trans(map(fill, divs), key, 1)
def decode(secret_message, key):
return trans(re.findall(r'..', secret_message), key, -1)
Sept. 17, 2014