-
Notifications
You must be signed in to change notification settings - Fork 0
/
AffineCypher.py
219 lines (150 loc) · 5.2 KB
/
AffineCypher.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
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# This is the main file were I will the
# write the code of AFFINE CYPHER.
# Name = Day45,46,47,48,50.py
def alphabet():
alphabet = []
for i in range(65,91):
alphabet.append(chr(i))
return alphabet
alph = alphabet()
# Function that ask user to enter keys
def enterKey():
'''Ask user to enter key's'''
print("Enter keys:")
print('For Example: 4, 5')
keys = input('> ')
keyA, keyB = keys.split(',')
return int(keyA),int(keyB)
# Function to check if the enter key's are VAILD
def checkKey(keyA,keyB,mode):
'''Check if the entered KEY's are valid or not'''
if mode == 'encrypt' and keyA == 1 and keyB == 0:
print("This key effectively does not do any encrypt on the")
print("message. Choose a different key.")
return False
elif keyA < 0 or keyB < 0 or keyB > len(alph) - 1:
print('Key A must be greater than 0 and key B must be between')
print(f'0 and {len(alph-1)}')
return False
elif HCF(keyA,len(alph)) != 1:
print(f'Key A ({keyA}) and the symbol set')
print(f'size ({len(alph)}) are not relatively prime.')
print('Choose a different key.')
return False
return True
# Function to ask user to (e)ncrypt or (d)ecrypt text
def encryptOrDecryptMessage():
'''ask user to encrypt or decrypt a message'''
while True:
print()
print("Type (e) to 'encrypt' or,")
print("(d) to 'decrypt'.")
mode = input('> ')
if mode.lower().startswith('e'):
# User want to encrypt the message
myMode = 'encrypt'
return myMode
elif mode.lower().startswith('d'):
# User want to decrypt the message
myMode = 'decrypt'
return myMode
print('INVALID INPUT!!!')
# Function to encrypt text
def encryptText(word,keyA,keyB):
'''To encrypt the plane text'''
keyA,keyB=int(keyA),int(keyB)
new_word = ''
for i in word:
letter_index = alph.index(i.upper())
new_index = ((keyA * letter_index) + keyB) % 26
new_word += alph[new_index]
return new_word
# Function to decrypt text
def decryptText(word,keyA,keyB):
'''TO decrypt the encrypt text.'''
keyA,keyB=int(keyA),int(keyB)
new_word = ''
# Finding the inverse of KeyA
inverseKeyA = modular_inverse(keyA,len(alph))
for i in word:
letter_index = alph.index(i.upper())
new_index = (letter_index - keyB) * inverseKeyA % len(alph)
new_word += alph[new_index]
return new_word
# Function to find the HCF
def HCF(a, b):
while b:
a, b = b, a % b
return a
# Function to find modular Inverse
def modular_inverse(a, m):
try:
inverse = pow(a , -1 , m)
return inverse
except:
raise ValueError("Inverse does not exist for this pair of numbers.")
# Function to ask user to PLAY AGAIN!
def playAgain():
print("Do you want to play Again?[y, n]")
option = input('> ')
if option.lower().startswith('y'):
return True
else:
return False
# Main Loop
while True:
# Asking user to enter the message
print("Enter message...")
message = input('> ')
# Asking user to encrypt or decrypt the message
myMode = encryptOrDecryptMessage()
# Asking user to enter key's
while True:
# Enter key
keyA,KeyB = enterKey()
if checkKey(keyA,KeyB,myMode):
# if True mean VALID KEY'S
break
print('INVALID KEYS')
print()
# encrypting the message
plane_word = []
for word in message.split():
crypto_txt = ''
# Seprate the non-letter at the start of the text
prefixNonLetters = ''
while len(word) > 0 and not word[0].isalpha():
prefixNonLetters += word[0]
word = word[1:]
if len(word) == 0:
plane_word.append(prefixNonLetters)
continue
# Seprate the non-letter at the end of the text
suffixNonLetters = ''
while not word[-1].isalpha():
suffixNonLetters = word[-1] + suffixNonLetters
word = word[:-1]
# Rembember if the word was in upperCase or title Case.
wasUpper = word.isupper()
wasTitle = word.istitle()
word = word.lower() # make the word lowercase for translation.
# modifing the letter's
if myMode.lower().startswith('e'):
# Then encrypt the message
crypto_txt += encryptText(word,keyA,KeyB)
else:
# Then decrypt the message
crypto_txt += decryptText(word,keyA,KeyB)
# Set the word back to uppercase or title case:
if wasUpper:
word = crypto_txt.upper()
if wasTitle:
word = crypto_txt.title()
# Add the non-letters back to the start or end of the word.
plane_word.append(prefixNonLetters + crypto_txt + suffixNonLetters)
# Join all the words back together into a single string:
sentence = ' '.join(plane_word)
print(sentence)
if playAgain():
continue
break