-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimplementation_of_playfair_cipher.py
More file actions
186 lines (144 loc) · 5.42 KB
/
implementation_of_playfair_cipher.py
File metadata and controls
186 lines (144 loc) · 5.42 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def convertPlainTextToDiagraphs (plainText):
# append X if Two letters are being repeated
for s in range(0,len(plainText)+1,2):
if s<len(plainText)-1:
if plainText[s]==plainText[s+1]:
plainText=plainText[:s+1]+'X'+plainText[s+1:]
# append X if the total letters are odd, to make plaintext even
if len(plainText)%2 != 0:
plainText = plainText[:]+'X'
return plainText
def generateKeyMatrix (key):
# Intially Create 5X5 matrix with all values as 0
# [
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0]
# ]
matrix_5x5 = [[0 for i in range (5)] for j in range(5)]
simpleKeyArr = []
"""
Generate SimpleKeyArray with key from user Input
with following below condition:
1. Character Should not be repeated again
2. Replacing J as I (as per rule of playfair cipher)
"""
for c in key:
if c not in simpleKeyArr:
if c == 'J':
simpleKeyArr.append('I')
else:
simpleKeyArr.append(c)
"""
Fill the remaining SimpleKeyArray with rest of unused letters from english alphabets
"""
is_I_exist = "I" in simpleKeyArr
# A-Z's ASCII Value lies between 65 to 90 but as range's second parameter excludes that value we will use 65 to 91
for i in range(65,91):
if chr(i) not in simpleKeyArr:
# I = 73
# J = 74
# We want I in simpleKeyArr not J
if i==73 and not is_I_exist:
simpleKeyArr.append("I")
is_I_exist = True
elif i==73 or i==74 and is_I_exist:
pass
else:
simpleKeyArr.append(chr(i))
"""
Now map simpleKeyArr to matrix_5x5
"""
index = 0
for i in range(0,5):
for j in range(0,5):
matrix_5x5[i][j] = simpleKeyArr[index]
index+=1
return matrix_5x5
def indexLocator (char,cipherKeyMatrix):
indexOfChar = []
# convert the character value from J to I
if char=="J":
char = "I"
for i,j in enumerate(cipherKeyMatrix):
# enumerate will return object like this:
# [
# (0, ['K', 'A', 'R', 'E', 'N']),
# (1, ['D', 'B', 'C', 'F', 'G']),
# (2, ['H', 'I', 'L', 'M', 'O']),
# (3, ['P', 'Q', 'S', 'T', 'U']),
# (4, ['V', 'W', 'X', 'Y', 'Z'])
# ]
# i,j will map to tupels of above array
# j refers to inside matrix => ['K', 'A', 'R', 'E', 'N'],
for k,l in enumerate(j):
# again enumerate will return object that look like this in first iteration:
# [(0,'K'),(1,'A'),(2,'R'),(3,'E'),(4,'N')]
# k,l will map to tupels of above array
if char == l:
indexOfChar.append(i) #add 1st dimension of 5X5 matrix => i.e., indexOfChar = [i]
indexOfChar.append(k) #add 2nd dimension of 5X5 matrix => i.e., indexOfChar = [i,k]
return indexOfChar
# Now with the help of indexOfChar = [i,k] we can pretty much locate every element,
# inside our 5X5 matrix like this => cipherKeyMatrix[i][k]
def encryption (plainText,key):
cipherText = []
# 1. Generate Key Matrix
keyMatrix = generateKeyMatrix(key)
# 2. Encrypt According to Rules of playfair cipher
i = 0
while i < len(plainText):
# 2.1 calculate two grouped characters indexes from keyMatrix
n1 = indexLocator(plainText[i],keyMatrix)
n2 = indexLocator(plainText[i+1],keyMatrix)
# 2.2 if same column then look in below row so
# format is [row,col]
# now to see below row => increase the row in both item
# (n1[0]+1,n1[1]) => (3+1,1) => (4,1)
# (n2[0]+1,n2[1]) => (4+1,1) => (5,1)
# but in our matrix we have 0 to 4 indexes only
# so to make value bound under 0 to 4 we will do %5
# i.e.,
# (n1[0]+1 % 5,n1[1])
# (n2[0]+1 % 5,n2[1])
if n1[1] == n2[1]:
i1 = (n1[0] + 1) % 5
j1 = n1[1]
i2 = (n2[0] + 1) % 5
j2 = n2[1]
cipherText.append(keyMatrix[i1][j1])
cipherText.append(keyMatrix[i2][j2])
cipherText.append(", ")
# same row
elif n1[0]==n2[0]:
i1= n1[0]
j1= (n1[1] + 1) % 5
i2= n2[0]
j2= (n2[1] + 1) % 5
cipherText.append(keyMatrix[i1][j1])
cipherText.append(keyMatrix[i2][j2])
cipherText.append(", ")
# if making rectangle then
# [4,3] [1,2] => [4,2] [3,1]
# exchange columns of both value
else:
i1 = n1[0]
j1 = n1[1]
i2 = n2[0]
j2 = n2[1]
cipherText.append(keyMatrix[i1][j2])
cipherText.append(keyMatrix[i2][j1])
cipherText.append(", ")
i += 2
return cipherText
def main():
#Getting user inputs Key (to make the 5x5 char matrix) and Plain Text (Message that is to be encripted)
key = input("Enter key: ").replace(" ","").upper()
plainText =input("Plain Text: ").replace(" ","").upper()
convertedPlainText = convertPlainTextToDiagraphs(plainText)
cipherText = " ".join(encryption(convertedPlainText,key))
print(cipherText)
if __name__ == "__main__":
main()