@@ -183,15 +183,15 @@ def process_text(self, text: str) -> str:
183
183
'ABCC'
184
184
"""
185
185
chars = [char for char in text .upper () if char in self .key_string ]
186
-
186
+
187
187
# Handle empty input case
188
188
if not chars :
189
189
return ""
190
-
190
+
191
191
last = chars [- 1 ]
192
192
while len (chars ) % self .break_key != 0 :
193
193
chars .append (last )
194
-
194
+
195
195
return "" .join (chars )
196
196
197
197
def encrypt (self , text : str ) -> str :
@@ -221,21 +221,21 @@ def encrypt(self, text: str) -> str:
221
221
text = self .process_text (text .upper ())
222
222
if not text :
223
223
return ""
224
-
224
+
225
225
encrypted = ""
226
226
227
227
for i in range (0 , len (text ) - self .break_key + 1 , self .break_key ):
228
228
# Extract batch of characters
229
229
batch = text [i : i + self .break_key ]
230
-
230
+
231
231
# Convert to numerical vector
232
232
vec = [self .replace_letters (char ) for char in batch ]
233
233
batch_vec = np .array ([vec ]).T
234
-
234
+
235
235
# Matrix multiplication and mod 36
236
236
product = self .encrypt_key .dot (batch_vec )
237
237
batch_encrypted = self .modulus (product ).T .tolist ()[0 ]
238
-
238
+
239
239
# Convert back to characters
240
240
encrypted_batch = "" .join (
241
241
self .replace_digits (num ) for num in batch_encrypted
@@ -244,7 +244,6 @@ def encrypt(self, text: str) -> str:
244
244
245
245
return encrypted
246
246
247
-
248
247
def make_decrypt_key (self ) -> np .ndarray :
249
248
"""
250
249
Compute decryption key matrix from encryption key.
@@ -261,7 +260,7 @@ def make_decrypt_key(self) -> np.ndarray:
261
260
>>> cipher.make_decrypt_key()
262
261
array([[ 6, 25],
263
262
[ 5, 26]])
264
-
263
+
265
264
>>> key3x3 = np.array([[1,2,3],[4,5,6],[7,8,9]])
266
265
>>> cipher3 = HillCipher(key3x3)
267
266
>>> cipher3.make_decrypt_key() # Determinant 0 should be invalid
@@ -275,7 +274,7 @@ def make_decrypt_key(self) -> np.ndarray:
275
274
276
275
if det < 0 :
277
276
det = det % len (self .key_string )
278
-
277
+
279
278
det_inv : int | None = None
280
279
for i in range (len (self .key_string )):
281
280
if (det * i ) % len (self .key_string ) == 1 :
@@ -318,22 +317,22 @@ def decrypt(self, text: str) -> str:
318
317
text = self .process_text (text .upper ())
319
318
if not text :
320
319
return ""
321
-
320
+
322
321
decrypt_key = self .make_decrypt_key ()
323
322
decrypted = ""
324
323
325
324
for i in range (0 , len (text ) - self .break_key + 1 , self .break_key ):
326
325
# Extract batch of characters
327
326
batch = text [i : i + self .break_key ]
328
-
327
+
329
328
# Convert to numerical vector
330
329
vec = [self .replace_letters (char ) for char in batch ]
331
330
batch_vec = np .array ([vec ]).T
332
-
331
+
333
332
# Matrix multiplication and mod 36
334
333
product = decrypt_key .dot (batch_vec )
335
334
batch_decrypted = self .modulus (product ).T .tolist ()[0 ]
336
-
335
+
337
336
# Convert back to characters
338
337
decrypted_batch = "" .join (
339
338
self .replace_digits (num ) for num in batch_decrypted
@@ -346,7 +345,7 @@ def decrypt(self, text: str) -> str:
346
345
def main () -> None :
347
346
"""
348
347
Command-line interface for Hill Cipher operations.
349
-
348
+
350
349
Steps:
351
350
1. User inputs encryption key size
352
351
2. User inputs encryption key matrix rows
@@ -359,14 +358,14 @@ def main() -> None:
359
358
360
359
print ("Enter each row of the encryption key with space separated integers" )
361
360
for i in range (n ):
362
- row = [int (x ) for x in input (f"Row { i + 1 } : " ).split ()]
361
+ row = [int (x ) for x in input (f"Row { i + 1 } : " ).split ()]
363
362
hill_matrix .append (row )
364
363
365
364
hc = HillCipher (np .array (hill_matrix ))
366
365
367
366
print ("\n Would you like to encrypt or decrypt some text?" )
368
367
option = input ("1. Encrypt\n 2. Decrypt\n Enter choice (1/2): " )
369
-
368
+
370
369
if option == "1" :
371
370
text = input ("\n Enter text to encrypt: " )
372
371
print ("\n Encrypted text:" )
@@ -381,20 +380,21 @@ def main() -> None:
381
380
382
381
if __name__ == "__main__" :
383
382
import doctest
383
+
384
384
doctest .testmod ()
385
-
385
+
386
386
print ("\n Running sample tests..." )
387
387
key = np .array ([[2 , 5 ], [1 , 6 ]])
388
388
cipher = HillCipher (key )
389
-
389
+
390
390
# Test encryption/decryption round trip
391
391
plaintext = "HELLO123"
392
392
encrypted = cipher .encrypt (plaintext )
393
393
decrypted = cipher .decrypt (encrypted )
394
-
394
+
395
395
print (f"\n Original text: { plaintext } " )
396
396
print (f"Encrypted text: { encrypted } " )
397
397
print (f"Decrypted text: { decrypted } " )
398
-
398
+
399
399
# Run CLI interface
400
400
main ()
0 commit comments