@@ -121,7 +121,6 @@ def replace_digits(self, num: int) -> str:
121121 """
122122 return self .key_string [round (num )]
123123
124-
125124 def check_determinant (self ) -> None :
126125 """
127126 Validate encryption key determinant.
@@ -152,7 +151,7 @@ def check_determinant(self) -> None:
152151 det_value = np .linalg .det (self .encrypt_key )
153152 # Only round if necessary
154153 det = int (det_value ) if det_value .is_integer () else int (round (det_value ))
155-
154+
156155 if det < 0 :
157156 det = det % len (self .key_string )
158157
@@ -164,7 +163,6 @@ def check_determinant(self) -> None:
164163 )
165164 raise ValueError (msg )
166165
167-
168166 def process_text (self , text : str ) -> str :
169167 """
170168 Prepare text for encryption/decryption by:
@@ -191,15 +189,15 @@ def process_text(self, text: str) -> str:
191189 'ABCC'
192190 """
193191 chars = [char for char in text .upper () if char in self .key_string ]
194-
192+
195193 # Handle empty input case
196194 if not chars :
197195 return ""
198-
196+
199197 last = chars [- 1 ]
200198 while len (chars ) % self .break_key != 0 :
201199 chars .append (last )
202-
200+
203201 return "" .join (chars )
204202
205203 def encrypt (self , text : str ) -> str :
@@ -229,21 +227,21 @@ def encrypt(self, text: str) -> str:
229227 text = self .process_text (text .upper ())
230228 if not text :
231229 return ""
232-
230+
233231 encrypted = ""
234232
235233 for i in range (0 , len (text ) - self .break_key + 1 , self .break_key ):
236234 # Extract batch of characters
237235 batch = text [i : i + self .break_key ]
238-
236+
239237 # Convert to numerical vector
240238 vec = [self .replace_letters (char ) for char in batch ]
241239 batch_vec = np .array ([vec ]).T
242-
240+
243241 # Matrix multiplication and mod 36
244242 product = self .encrypt_key .dot (batch_vec )
245243 batch_encrypted = self .modulus (product ).T .tolist ()[0 ]
246-
244+
247245 # Convert back to characters
248246 encrypted_batch = "" .join (
249247 self .replace_digits (num ) for num in batch_encrypted
@@ -268,7 +266,7 @@ def make_decrypt_key(self) -> np.ndarray:
268266 >>> cipher.make_decrypt_key()
269267 array([[ 6, 25],
270268 [ 5, 26]])
271-
269+
272270 >>> key3x3 = np.array([[1,2,3],[4,5,6],[7,8,9]])
273271 >>> cipher3 = HillCipher(key3x3)
274272 >>> cipher3.make_decrypt_key() # Determinant 0 should be invalid
@@ -280,10 +278,10 @@ def make_decrypt_key(self) -> np.ndarray:
280278 det_value = np .linalg .det (self .encrypt_key )
281279 # Only round if necessary
282280 det = int (det_value ) if det_value .is_integer () else int (round (det_value ))
283-
281+
284282 if det < 0 :
285283 det = det % len (self .key_string )
286-
284+
287285 det_inv : int | None = None
288286 for i in range (len (self .key_string )):
289287 if (det * i ) % len (self .key_string ) == 1 :
@@ -326,22 +324,22 @@ def decrypt(self, text: str) -> str:
326324 text = self .process_text (text .upper ())
327325 if not text :
328326 return ""
329-
327+
330328 decrypt_key = self .make_decrypt_key ()
331329 decrypted = ""
332330
333331 for i in range (0 , len (text ) - self .break_key + 1 , self .break_key ):
334332 # Extract batch of characters
335333 batch = text [i : i + self .break_key ]
336-
334+
337335 # Convert to numerical vector
338336 vec = [self .replace_letters (char ) for char in batch ]
339337 batch_vec = np .array ([vec ]).T
340-
338+
341339 # Matrix multiplication and mod 36
342340 product = decrypt_key .dot (batch_vec )
343341 batch_decrypted = self .modulus (product ).T .tolist ()[0 ]
344-
342+
345343 # Convert back to characters
346344 decrypted_batch = "" .join (
347345 self .replace_digits (num ) for num in batch_decrypted
@@ -354,7 +352,7 @@ def decrypt(self, text: str) -> str:
354352def main () -> None :
355353 """
356354 Command-line interface for Hill Cipher operations.
357-
355+
358356 Steps:
359357 1. User inputs encryption key size
360358 2. User inputs encryption key matrix rows
@@ -367,14 +365,14 @@ def main() -> None:
367365
368366 print ("Enter each row of the encryption key with space separated integers" )
369367 for i in range (n ):
370- row = [int (x ) for x in input (f"Row { i + 1 } : " ).split ()]
368+ row = [int (x ) for x in input (f"Row { i + 1 } : " ).split ()]
371369 hill_matrix .append (row )
372370
373371 hc = HillCipher (np .array (hill_matrix ))
374372
375373 print ("\n Would you like to encrypt or decrypt some text?" )
376374 option = input ("1. Encrypt\n 2. Decrypt\n Enter choice (1/2): " )
377-
375+
378376 if option == "1" :
379377 text = input ("\n Enter text to encrypt: " )
380378 print ("\n Encrypted text:" )
@@ -389,20 +387,21 @@ def main() -> None:
389387
390388if __name__ == "__main__" :
391389 import doctest
390+
392391 doctest .testmod ()
393-
392+
394393 print ("\n Running sample tests..." )
395394 key = np .array ([[2 , 5 ], [1 , 6 ]])
396395 cipher = HillCipher (key )
397-
396+
398397 # Test encryption/decryption round trip
399398 plaintext = "HELLO123"
400399 encrypted = cipher .encrypt (plaintext )
401400 decrypted = cipher .decrypt (encrypted )
402-
401+
403402 print (f"\n Original text: { plaintext } " )
404403 print (f"Encrypted text: { encrypted } " )
405404 print (f"Decrypted text: { decrypted } " )
406-
405+
407406 # Run CLI interface
408407 main ()
0 commit comments