-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathplay_fair_cipher.py
142 lines (111 loc) · 3.4 KB
/
play_fair_cipher.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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
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):
'''
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:
return i, j
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)
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):
'''
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:
new_pairs.append(find_new_pairs(pair, key, encrypt=True))
return ''.join(a+b for a, b in new_pairs)
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:
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):
'''
This function creates a 5x5 matrix for the given key
'''
all_elements = []
# 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('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 = 'theworkingbros'.replace(' ', '').upper()
key = 'risinglight'.replace(' ', '').upper()
# main calling function
playfair(text, key=create_key(key))
# This code is contributed by Bhushan Borole