From b29cc98530328c6ec636979abd23932cc980272d Mon Sep 17 00:00:00 2001 From: bhushan-borole <37565807+bhushan-borole@users.noreply.github.com> Date: Sat, 12 Oct 2019 12:45:38 +0530 Subject: [PATCH 1/2] Added Play Fair Cipher --- Ciphers/play_fair_cipher.py | 98 +++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 Ciphers/play_fair_cipher.py diff --git a/Ciphers/play_fair_cipher.py b/Ciphers/play_fair_cipher.py new file mode 100644 index 0000000..0f23318 --- /dev/null +++ b/Ciphers/play_fair_cipher.py @@ -0,0 +1,98 @@ +import string + + +def get_pairs_of_text(text): + pairs = [] + i = 0 + + while i < len(text): + a = text[i] + try: + b = text[i+1] + except Exception as e: + pairs.append((a, 'X')) + break + + if a == b: + pairs.append((a, 'X')) + i += 1 + else: + pairs.append((a, b)) + i += 2 + return pairs + + +def get_index(k, key): + for i in range(5): + for j in range(5): + if key[i][j] == k: + return i, j + + +def find_new_pairs(pair, key, encrypt): + a, b = pair + ai, aj = get_index(a, key) + bi, bj = get_index(b, key) + + if ai == bi: + if encrypt: # move right + aj = (aj + 1) % 5 + bj = (bj + 1) % 5 + else: # move left + aj = (aj - 1) % 5 + bj = (bj - 1) % 5 + elif aj == bj: + if encrypt: # move down + ai = (ai + 1) % 5 + bi = (bi + 1) % 5 + else: # move up + ai = (ai - 1) % 5 + bi = (bi - 1) % 5 + else: + aj, bj = bj, aj + + return (key[ai][aj], key[bi][bj]) + + +def encrypt(text, key): + pairs = get_pairs_of_text(text) + new_pairs = [] + for pair in pairs: + new_pairs.append(find_new_pairs(pair, key, encrypt=True)) + return ''.join(a+b for a, b in new_pairs) + + +def decrypt(text, key): + pairs = get_pairs_of_text(text) + new_pairs = [] + for pair in pairs: + new_pairs.append(find_new_pairs(pair, key, encrypt=False)) + return ''.join(a+b for a, b in new_pairs).replace('X', '') + + +def create_key(key): + all_elements = [] + elements = list(key + string.ascii_uppercase.replace('J', '')) + for el in elements: + if not el in all_elements: + all_elements.append(el) + + KEY = [] + for i in range(0, 25, 5): + KEY.append(all_elements[i:i+5]) + + return KEY + + +def playfair(text, key): + print('Original Text: ', text) + enc = encrypt(text, key=key) + print('Encrypted Text: ', enc) + dec = decrypt(enc, key=key) + print('Decrypted Text: ', dec) + + +if __name__ == '__main__': + text = 'BALLOON' + key = 'BALLOON' + playfair(text, key=create_key(key)) From 2eecd1d1d4e2aa7462ba06fda36f3e81b3aa3434 Mon Sep 17 00:00:00 2001 From: bhushan-borole <37565807+bhushan-borole@users.noreply.github.com> Date: Mon, 14 Oct 2019 07:08:42 +0530 Subject: [PATCH 2/2] Updated the main function to remove lowercase-uppercase bug --- Ciphers/play_fair_cipher.py | 52 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/Ciphers/play_fair_cipher.py b/Ciphers/play_fair_cipher.py index 0f23318..c578ddd 100644 --- a/Ciphers/play_fair_cipher.py +++ b/Ciphers/play_fair_cipher.py @@ -1,7 +1,13 @@ import string +from pprint import pprint def get_pairs_of_text(text): + ''' + This function generates pairs of elements + from the given text. + eg: BALLOON becomes BA LX LO ON + ''' pairs = [] i = 0 @@ -23,6 +29,10 @@ def get_pairs_of_text(text): def get_index(k, key): + ''' + This function returns the index of the specified element + inside the key matrix. + ''' for i in range(5): for j in range(5): if key[i][j] == k: @@ -30,6 +40,10 @@ def get_index(k, key): def find_new_pairs(pair, key, encrypt): + ''' + This is the function which returns a tuple consisting of new characters + based on the pair given as input. + ''' a, b = pair ai, aj = get_index(a, key) bi, bj = get_index(b, key) @@ -55,6 +69,11 @@ def find_new_pairs(pair, key, encrypt): def encrypt(text, key): + ''' + This is the main encrypt function + ''' + + # here we generate pairs of the original text pairs = get_pairs_of_text(text) new_pairs = [] for pair in pairs: @@ -63,6 +82,11 @@ def encrypt(text, key): def decrypt(text, key): + ''' + This is the main decrypt function. + ''' + + # here we generate pairs of the cipher text pairs = get_pairs_of_text(text) new_pairs = [] for pair in pairs: @@ -71,28 +95,48 @@ def decrypt(text, key): def create_key(key): + ''' + This function creates a 5x5 matrix for the given key + ''' all_elements = [] - elements = list(key + string.ascii_uppercase.replace('J', '')) + + # this list contains those elements which are not present in the key + list_of_non_keys = list(set(list(string.ascii_uppercase)) - set(list(key))) + + # generating a list of 25 characters by removing the one which is not present in the key + elements = list(key + string.ascii_uppercase.replace(list_of_non_keys[0], '')) for el in elements: if not el in all_elements: all_elements.append(el) KEY = [] + # adding the elements to the matrix for i in range(0, 25, 5): KEY.append(all_elements[i:i+5]) + print("Key Matrix: ") + pprint(KEY) + return KEY def playfair(text, key): print('Original Text: ', text) + + # the encrypted function is passed the text and the key as parameters. enc = encrypt(text, key=key) - print('Encrypted Text: ', enc) + print('Cipher Text: ', enc) + + # the decrypt function is passed the cipher text and the key as parameters. dec = decrypt(enc, key=key) print('Decrypted Text: ', dec) if __name__ == '__main__': - text = 'BALLOON' - key = 'BALLOON' + text = 'theworkingbros'.replace(' ', '').upper() + key = 'risinglight'.replace(' ', '').upper() + + # main calling function playfair(text, key=create_key(key)) + +# This code is contributed by Bhushan Borole \ No newline at end of file