Skip to content

Commit 5d9b6ad

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

1 file changed

Lines changed: 14 additions & 12 deletions

File tree

ciphers/hill_cipher.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from maths.greatest_common_divisor import greatest_common_divisor
66

7+
78
class HillCipher:
89
key_string = string.ascii_uppercase + string.digits # 36 chars
910
modulus = np.vectorize(lambda x: x % 36) # Mod 36
@@ -27,15 +28,15 @@ def check_determinant(self) -> None:
2728
det = round(np.linalg.det(self.encrypt_key))
2829
if det < 0:
2930
det %= len(self.key_string)
30-
31+
3132
error_msg = f"Det {det} not coprime with 36. Try another key."
3233
if greatest_common_divisor(det, len(self.key_string)) != 1:
3334
raise ValueError(error_msg)
3435

3536
def process_text(self, text: str) -> str:
3637
"""Uppercase, filter, pad text"""
3738
chars = [c for c in text.upper() if c in self.key_string]
38-
last = chars[-1] if chars else 'A'
39+
last = chars[-1] if chars else "A"
3940
while len(chars) % self.break_key != 0:
4041
chars.append(last)
4142
return "".join(chars)
@@ -45,7 +46,7 @@ def encrypt(self, text: str) -> str:
4546
text = self.process_text(text.upper())
4647
encrypted = ""
4748
for i in range(0, len(text), self.break_key):
48-
batch = text[i:i+self.break_key]
49+
batch = text[i : i + self.break_key]
4950
vec = [self.replace_letters(c) for c in batch]
5051
batch_vec = np.array([vec]).T
5152
product = self.encrypt_key.dot(batch_vec)
@@ -62,15 +63,13 @@ def make_decrypt_key(self) -> np.ndarray:
6263
det = round(np.linalg.det(self.encrypt_key))
6364
if det < 0:
6465
det %= len(self.key_string)
65-
66+
6667
# Find det modular inverse
6768
det_inv = next(i for i in range(36) if (det * i) % 36 == 1)
68-
69+
6970
# Compute inverse key
7071
inv_key = (
71-
det_inv *
72-
np.linalg.det(self.encrypt_key) *
73-
np.linalg.inv(self.encrypt_key)
72+
det_inv * np.linalg.det(self.encrypt_key) * np.linalg.inv(self.encrypt_key)
7473
)
7574
return self.to_int(self.modulus(inv_key))
7675

@@ -80,7 +79,7 @@ def decrypt(self, text: str) -> str:
8079
text = self.process_text(text.upper())
8180
decrypted = ""
8281
for i in range(0, len(text), self.break_key):
83-
batch = text[i:i+self.break_key]
82+
batch = text[i : i + self.break_key]
8483
vec = [self.replace_letters(c) for c in batch]
8584
batch_vec = np.array([vec]).T
8685
product = decrypt_key.dot(batch_vec)
@@ -92,23 +91,26 @@ def decrypt(self, text: str) -> str:
9291
decrypted += decrypted_batch
9392
return decrypted
9493

94+
9595
def main() -> None:
9696
"""Hill Cipher CLI"""
9797
n = int(input("Enter key order: "))
9898
print(f"Enter {n} rows of space-separated integers:")
9999
matrix = [list(map(int, input().split())) for _ in range(n)]
100-
100+
101101
hc = HillCipher(np.array(matrix))
102-
102+
103103
option = input("1. Encrypt\n2. Decrypt\nChoose: ")
104104
text = input("Enter text: ")
105-
105+
106106
if option == "1":
107107
print("Encrypted:", hc.encrypt(text))
108108
elif option == "2":
109109
print("Decrypted:", hc.decrypt(text))
110110

111+
111112
if __name__ == "__main__":
112113
import doctest
114+
113115
doctest.testmod()
114116
main()

0 commit comments

Comments
 (0)