Skip to content

Commit 5fa46b8

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 6e83656 commit 5fa46b8

File tree

1 file changed

+26
-23
lines changed

1 file changed

+26
-23
lines changed

ciphers/hill_cipher.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def check_determinant(self) -> None:
146146
# Optimized determinant calculation to avoid redundant rounding
147147
det_value = np.linalg.det(self.encrypt_key)
148148
det = int(round(det_value)) if not det_value.is_integer() else int(det_value)
149-
149+
150150
if det < 0:
151151
det = det % len(self.key_string)
152152

@@ -157,6 +157,7 @@ def check_determinant(self) -> None:
157157
f"w.r.t {req_l}.\nTry another key."
158158
)
159159
raise ValueError(msg)
160+
160161
def process_text(self, text: str) -> str:
161162
"""
162163
Prepare text for encryption/decryption by:
@@ -183,16 +184,17 @@ def process_text(self, text: str) -> str:
183184
'ABCC'
184185
"""
185186
chars = [char for char in text.upper() if char in self.key_string]
186-
187+
187188
# Handle empty input case
188189
if not chars:
189190
return ""
190-
191+
191192
last = chars[-1]
192193
while len(chars) % self.break_key != 0:
193194
chars.append(last)
194-
195+
195196
return "".join(chars)
197+
196198
def encrypt(self, text: str) -> str:
197199
"""
198200
Encrypt plaintext using Hill Cipher.
@@ -220,21 +222,21 @@ def encrypt(self, text: str) -> str:
220222
text = self.process_text(text.upper())
221223
if not text:
222224
return ""
223-
225+
224226
encrypted = ""
225227

226228
for i in range(0, len(text) - self.break_key + 1, self.break_key):
227229
# Extract batch of characters
228230
batch = text[i : i + self.break_key]
229-
231+
230232
# Convert to numerical vector
231233
vec = [self.replace_letters(char) for char in batch]
232234
batch_vec = np.array([vec]).T
233-
235+
234236
# Matrix multiplication and mod 36
235237
product = self.encrypt_key.dot(batch_vec)
236238
batch_encrypted = self.modulus(product).T.tolist()[0]
237-
239+
238240
# Convert back to characters
239241
encrypted_batch = "".join(
240242
self.replace_digits(num) for num in batch_encrypted
@@ -259,7 +261,7 @@ def make_decrypt_key(self) -> np.ndarray:
259261
>>> cipher.make_decrypt_key()
260262
array([[ 6, 25],
261263
[ 5, 26]])
262-
264+
263265
>>> key3x3 = np.array([[1,2,3],[4,5,6],[7,8,9]])
264266
>>> cipher3 = HillCipher(key3x3)
265267
>>> cipher3.make_decrypt_key() # Determinant 0 should be invalid
@@ -271,10 +273,10 @@ def make_decrypt_key(self) -> np.ndarray:
271273
# Optimized determinant calculation to avoid redundant rounding
272274
det_value = np.linalg.det(self.encrypt_key)
273275
det = int(round(det_value)) if not det_value.is_integer() else int(det_value)
274-
276+
275277
if det < 0:
276278
det = det % len(self.key_string)
277-
279+
278280
det_inv: int | None = None
279281
for i in range(len(self.key_string)):
280282
if (det * i) % len(self.key_string) == 1:
@@ -317,22 +319,22 @@ def decrypt(self, text: str) -> str:
317319
text = self.process_text(text.upper())
318320
if not text:
319321
return ""
320-
322+
321323
decrypt_key = self.make_decrypt_key()
322324
decrypted = ""
323325

324326
for i in range(0, len(text) - self.break_key + 1, self.break_key):
325327
# Extract batch of characters
326328
batch = text[i : i + self.break_key]
327-
329+
328330
# Convert to numerical vector
329331
vec = [self.replace_letters(char) for char in batch]
330332
batch_vec = np.array([vec]).T
331-
333+
332334
# Matrix multiplication and mod 36
333335
product = decrypt_key.dot(batch_vec)
334336
batch_decrypted = self.modulus(product).T.tolist()[0]
335-
337+
336338
# Convert back to characters
337339
decrypted_batch = "".join(
338340
self.replace_digits(num) for num in batch_decrypted
@@ -342,11 +344,10 @@ def decrypt(self, text: str) -> str:
342344
return decrypted
343345

344346

345-
346347
def main() -> None:
347348
"""
348349
Command-line interface for Hill Cipher operations.
349-
350+
350351
Steps:
351352
1. User inputs encryption key size
352353
2. User inputs encryption key matrix rows
@@ -359,14 +360,14 @@ def main() -> None:
359360

360361
print("Enter each row of the encryption key with space separated integers")
361362
for i in range(n):
362-
row = [int(x) for x in input(f"Row {i+1}: ").split()]
363+
row = [int(x) for x in input(f"Row {i + 1}: ").split()]
363364
hill_matrix.append(row)
364365

365366
hc = HillCipher(np.array(hill_matrix))
366367

367368
print("\nWould you like to encrypt or decrypt some text?")
368369
option = input("1. Encrypt\n2. Decrypt\nEnter choice (1/2): ")
369-
370+
370371
if option == "1":
371372
text = input("\nEnter text to encrypt: ")
372373
print("\nEncrypted text:")
@@ -378,22 +379,24 @@ def main() -> None:
378379
else:
379380
print("Invalid option selected")
380381

382+
381383
if __name__ == "__main__":
382384
import doctest
385+
383386
doctest.testmod()
384-
387+
385388
print("\nRunning sample tests...")
386389
key = np.array([[2, 5], [1, 6]])
387390
cipher = HillCipher(key)
388-
391+
389392
# Test encryption/decryption round trip
390393
plaintext = "HELLO123"
391394
encrypted = cipher.encrypt(plaintext)
392395
decrypted = cipher.decrypt(encrypted)
393-
396+
394397
print(f"\nOriginal text: {plaintext}")
395398
print(f"Encrypted text: {encrypted}")
396399
print(f"Decrypted text: {decrypted}")
397-
400+
398401
# Run CLI interface
399402
main()

0 commit comments

Comments
 (0)