Skip to content

Commit 8510ac9

Browse files
committed
fix(mypy): type annotations for cipher algorithms
1 parent 14bcb58 commit 8510ac9

20 files changed

+190
-193
lines changed

Diff for: ciphers/diffie_hellman.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,7 @@ def generate_shared_key(self, other_key_str: str) -> str:
241241
return sha256(str(shared_key).encode()).hexdigest()
242242

243243
@staticmethod
244-
def is_valid_public_key_static(
245-
local_private_key_str: str, remote_public_key_str: str, prime: int
246-
) -> bool:
244+
def is_valid_public_key_static(remote_public_key_str: int, prime: int) -> bool:
247245
# check if the other public key is valid based on NIST SP800-56
248246
if 2 <= remote_public_key_str and remote_public_key_str <= prime - 2:
249247
if pow(remote_public_key_str, (prime - 1) // 2, prime) == 1:
@@ -257,9 +255,7 @@ def generate_shared_key_static(
257255
local_private_key = int(local_private_key_str, base=16)
258256
remote_public_key = int(remote_public_key_str, base=16)
259257
prime = primes[group]["prime"]
260-
if not DiffieHellman.is_valid_public_key_static(
261-
local_private_key, remote_public_key, prime
262-
):
258+
if not DiffieHellman.is_valid_public_key_static(remote_public_key, prime):
263259
raise ValueError("Invalid public key")
264260
shared_key = pow(remote_public_key, local_private_key, prime)
265261
return sha256(str(shared_key).encode()).hexdigest()

Diff for: ciphers/hill_cipher.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,12 @@ class HillCipher:
6464

6565
to_int = numpy.vectorize(lambda x: round(x))
6666

67-
def __init__(self, encrypt_key: int):
67+
def __init__(self, encrypt_key: numpy.ndarray) -> None:
6868
"""
6969
encrypt_key is an NxN numpy array
7070
"""
7171
self.encrypt_key = self.modulus(encrypt_key) # mod36 calc's on the encrypt key
7272
self.check_determinant() # validate the determinant of the encryption key
73-
self.decrypt_key = None
7473
self.break_key = encrypt_key.shape[0]
7574

7675
def replace_letters(self, letter: str) -> int:
@@ -151,7 +150,7 @@ def encrypt(self, text: str) -> str:
151150

152151
return encrypted
153152

154-
def make_decrypt_key(self):
153+
def make_decrypt_key(self) -> numpy.ndarray:
155154
"""
156155
>>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))
157156
>>> hill_cipher.make_decrypt_key()
@@ -184,17 +183,15 @@ def decrypt(self, text: str) -> str:
184183
>>> hill_cipher.decrypt('85FF00')
185184
'HELLOO'
186185
"""
187-
self.decrypt_key = self.make_decrypt_key()
186+
decrypt_key = self.make_decrypt_key()
188187
text = self.process_text(text.upper())
189188
decrypted = ""
190189

191190
for i in range(0, len(text) - self.break_key + 1, self.break_key):
192191
batch = text[i : i + self.break_key]
193192
batch_vec = [self.replace_letters(char) for char in batch]
194193
batch_vec = numpy.array([batch_vec]).T
195-
batch_decrypted = self.modulus(self.decrypt_key.dot(batch_vec)).T.tolist()[
196-
0
197-
]
194+
batch_decrypted = self.modulus(decrypt_key.dot(batch_vec)).T.tolist()[0]
198195
decrypted_batch = "".join(
199196
self.replace_digits(num) for num in batch_decrypted
200197
)
@@ -203,7 +200,7 @@ def decrypt(self, text: str) -> str:
203200
return decrypted
204201

205202

206-
def main():
203+
def main() -> None:
207204
N = int(input("Enter the order of the encryption key: "))
208205
hill_matrix = []
209206

Diff for: ciphers/mixed_keyword_cypher.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,32 @@ def mixed_keyword(key: str = "college", pt: str = "UNIVERSITY") -> str:
2929
# print(temp)
3030
alpha = []
3131
modalpha = []
32-
for i in range(65, 91):
33-
t = chr(i)
32+
for j in range(65, 91):
33+
t = chr(j)
3434
alpha.append(t)
3535
if t not in temp:
3636
temp.append(t)
3737
# print(temp)
3838
r = int(26 / 4)
3939
# print(r)
4040
k = 0
41-
for i in range(r):
42-
t = []
41+
for _ in range(r):
42+
s = []
4343
for j in range(len_temp):
44-
t.append(temp[k])
44+
s.append(temp[k])
4545
if not (k < 25):
4646
break
4747
k += 1
48-
modalpha.append(t)
48+
modalpha.append(s)
4949
# print(modalpha)
5050
d = {}
5151
j = 0
5252
k = 0
5353
for j in range(len_temp):
54-
for i in modalpha:
55-
if not (len(i) - 1 >= j):
54+
for m in modalpha:
55+
if not (len(m) - 1 >= j):
5656
break
57-
d[alpha[k]] = i[j]
57+
d[alpha[k]] = m[j]
5858
if not k < 25:
5959
break
6060
k += 1

Diff for: ciphers/mono_alphabetic_ciphers.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
from typing import Literal
2+
13
LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
24

35

4-
def translate_message(key, message, mode):
6+
def translate_message(
7+
key: str, message: str, mode: Literal["encrypt", "decrypt"]
8+
) -> str:
59
"""
610
>>> translate_message("QWERTYUIOPASDFGHJKLZXCVBNM","Hello World","encrypt")
711
'Pcssi Bidsm'
@@ -40,7 +44,7 @@ def decrypt_message(key: str, message: str) -> str:
4044
return translate_message(key, message, "decrypt")
4145

4246

43-
def main():
47+
def main() -> None:
4448
message = "Hello World"
4549
key = "QWERTYUIOPASDFGHJKLZXCVBNM"
4650
mode = "decrypt" # set to 'encrypt' or 'decrypt'

Diff for: ciphers/morse_code_implementation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def decrypt(message: str) -> str:
8383
return decipher
8484

8585

86-
def main():
86+
def main() -> None:
8787
message = "Morse code here"
8888
result = encrypt(message.upper())
8989
print(result)

Diff for: ciphers/onepad_cipher.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33

44
class Onepad:
5-
def encrypt(self, text: str) -> ([str], [int]):
5+
@staticmethod
6+
def encrypt(text: str) -> tuple[list[int], list[int]]:
67
"""Function to encrypt text using pseudo-random numbers"""
78
plain = [ord(i) for i in text]
89
key = []
@@ -14,14 +15,14 @@ def encrypt(self, text: str) -> ([str], [int]):
1415
key.append(k)
1516
return cipher, key
1617

17-
def decrypt(self, cipher: [str], key: [int]) -> str:
18+
@staticmethod
19+
def decrypt(cipher: list[int], key: list[int]) -> str:
1820
"""Function to decrypt text using pseudo-random numbers."""
1921
plain = []
2022
for i in range(len(key)):
2123
p = int((cipher[i] - (key[i]) ** 2) / key[i])
2224
plain.append(chr(p))
23-
plain = "".join([i for i in plain])
24-
return plain
25+
return "".join([i for i in plain])
2526

2627

2728
if __name__ == "__main__":

Diff for: ciphers/playfair_cipher.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import itertools
22
import string
3+
from typing import Generator, Iterable
34

45

5-
def chunker(seq, size):
6+
def chunker(seq: Iterable[str], size: int) -> Generator[tuple[str, ...], None, None]:
67
it = iter(seq)
78
while True:
89
chunk = tuple(itertools.islice(it, size))
@@ -37,7 +38,7 @@ def prepare_input(dirty: str) -> str:
3738
return clean
3839

3940

40-
def generate_table(key: str) -> [str]:
41+
def generate_table(key: str) -> list[str]:
4142

4243
# I and J are used interchangeably to allow
4344
# us to use a 5x5 table (25 letters)

Diff for: ciphers/porta_cipher.py

+21-28
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
}
2929

3030

31-
def generate_table(key: str) -> [(str, str)]:
31+
def generate_table(key: str) -> list[tuple[str, str]]:
3232
"""
3333
>>> generate_table('marvin') # doctest: +NORMALIZE_WHITESPACE
3434
[('ABCDEFGHIJKLM', 'UVWXYZNOPQRST'), ('ABCDEFGHIJKLM', 'NOPQRSTUVWXYZ'),
@@ -60,30 +60,21 @@ def decrypt(key: str, words: str) -> str:
6060
return encrypt(key, words)
6161

6262

63-
def get_position(table: [(str, str)], char: str) -> (int, int) or (None, None):
63+
def get_position(table: tuple[str, str], char: str) -> tuple[int, int]:
6464
"""
65-
>>> table = [
66-
... ('ABCDEFGHIJKLM', 'UVWXYZNOPQRST'), ('ABCDEFGHIJKLM', 'NOPQRSTUVWXYZ'),
67-
... ('ABCDEFGHIJKLM', 'STUVWXYZNOPQR'), ('ABCDEFGHIJKLM', 'QRSTUVWXYZNOP'),
68-
... ('ABCDEFGHIJKLM', 'WXYZNOPQRSTUV'), ('ABCDEFGHIJKLM', 'UVWXYZNOPQRST')]
69-
>>> get_position(table, 'A')
70-
(None, None)
65+
>>> get_position(generate_table('marvin')[0], 'M')
66+
(0, 12)
7167
"""
72-
if char in table[0]:
73-
row = 0
74-
else:
75-
row = 1 if char in table[1] else -1
76-
return (None, None) if row == -1 else (row, table[row].index(char))
68+
# `char` is either in the 0th row or the 1st row
69+
row = 0 if char in table[0] else 1
70+
col = table[row].index(char)
71+
return row, col
7772

7873

79-
def get_opponent(table: [(str, str)], char: str) -> str:
74+
def get_opponent(table: tuple[str, str], char: str) -> str:
8075
"""
81-
>>> table = [
82-
... ('ABCDEFGHIJKLM', 'UVWXYZNOPQRST'), ('ABCDEFGHIJKLM', 'NOPQRSTUVWXYZ'),
83-
... ('ABCDEFGHIJKLM', 'STUVWXYZNOPQR'), ('ABCDEFGHIJKLM', 'QRSTUVWXYZNOP'),
84-
... ('ABCDEFGHIJKLM', 'WXYZNOPQRSTUV'), ('ABCDEFGHIJKLM', 'UVWXYZNOPQRST')]
85-
>>> get_opponent(table, 'A')
86-
'A'
76+
>>> get_opponent(generate_table('marvin')[0], 'M')
77+
'T'
8778
"""
8879
row, col = get_position(table, char.upper())
8980
if row == 1:
@@ -97,14 +88,16 @@ def get_opponent(table: [(str, str)], char: str) -> str:
9788

9889
doctest.testmod() # Fist ensure that all our tests are passing...
9990
"""
100-
ENTER KEY: marvin
101-
ENTER TEXT TO ENCRYPT: jessica
102-
ENCRYPTED: QRACRWU
103-
DECRYPTED WITH KEY: JESSICA
91+
Demo:
92+
93+
Enter key: marvin
94+
Enter text to encrypt: jessica
95+
Encrypted: QRACRWU
96+
Decrypted with key: JESSICA
10497
"""
105-
key = input("ENTER KEY: ").strip()
106-
text = input("ENTER TEXT TO ENCRYPT: ").strip()
98+
key = input("Enter key: ").strip()
99+
text = input("Enter text to encrypt: ").strip()
107100
cipher_text = encrypt(key, text)
108101

109-
print(f"ENCRYPTED: {cipher_text}")
110-
print(f"DECRYPTED WITH KEY: {decrypt(key, cipher_text)}")
102+
print(f"Encrypted: {cipher_text}")
103+
print(f"Decrypted with key: {decrypt(key, cipher_text)}")

Diff for: ciphers/rail_fence_cipher.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def encrypt(input_string: str, key: int) -> str:
2020
...
2121
TypeError: sequence item 0: expected str instance, int found
2222
"""
23-
grid = [[] for _ in range(key)]
23+
temp_grid: list[list[str]] = [[] for _ in range(key)]
2424
lowest = key - 1
2525

2626
if key <= 0:
@@ -31,8 +31,8 @@ def encrypt(input_string: str, key: int) -> str:
3131
for position, character in enumerate(input_string):
3232
num = position % (lowest * 2) # puts it in bounds
3333
num = min(num, lowest * 2 - num) # creates zigzag pattern
34-
grid[num].append(character)
35-
grid = ["".join(row) for row in grid]
34+
temp_grid[num].append(character)
35+
grid = ["".join(row) for row in temp_grid]
3636
output_string = "".join(grid)
3737

3838
return output_string
@@ -63,7 +63,7 @@ def decrypt(input_string: str, key: int) -> str:
6363
if key == 1:
6464
return input_string
6565

66-
temp_grid = [[] for _ in range(key)] # generates template
66+
temp_grid: list[list[str]] = [[] for _ in range(key)] # generates template
6767
for position in range(len(input_string)):
6868
num = position % (lowest * 2) # puts it in bounds
6969
num = min(num, lowest * 2 - num) # creates zigzag pattern
@@ -84,7 +84,7 @@ def decrypt(input_string: str, key: int) -> str:
8484
return output_string
8585

8686

87-
def bruteforce(input_string: str) -> dict:
87+
def bruteforce(input_string: str) -> dict[int, str]:
8888
"""Uses decrypt function by guessing every key
8989
9090
>>> bruteforce("HWe olordll")[4]

Diff for: ciphers/rot13.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def dencrypt(s: str, n: int = 13) -> str:
2020
return out
2121

2222

23-
def main():
23+
def main() -> None:
2424
s0 = input("Enter message: ")
2525

2626
s1 = dencrypt(s0, 13)

0 commit comments

Comments
 (0)