-
Notifications
You must be signed in to change notification settings - Fork 0
/
hill.py
96 lines (87 loc) · 3.19 KB
/
hill.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import numpy as np
def encrypt(msg):
msg = msg.replace(" ", "")
C = make_key()
len_check = len(msg) % 2 == 0
if not len_check:
msg += "0"
P = create_matrix_of_integers_from_string(msg)
msg_len = int(len(msg) / 2)
encrypted_msg = ""
for i in range(msg_len):
row_0 = P[0][i] * C[0][0] + P[1][i] * C[0][1]
integer = int(row_0 % 26 + 65)
encrypted_msg += chr(integer)
row_1 = P[0][i] * C[1][0] + P[1][i] * C[1][1]
integer = int(row_1 % 26 + 65)
encrypted_msg += chr(integer)
return encrypted_msg
def decrypt(encrypted_msg):
C = make_key()
determinant = C[0][0] * C[1][1] - C[0][1] * C[1][0]
determinant = determinant % 26
multiplicative_inverse = find_multiplicative_inverse(determinant)
C_inverse = C
C_inverse[0][0], C_inverse[1][1] = C_inverse[1, 1], C_inverse[0, 0]
C[0][1] *= -1
C[1][0] *= -1
for row in range(2):
for column in range(2):
C_inverse[row][column] *= multiplicative_inverse
C_inverse[row][column] = C_inverse[row][column] % 26
P = create_matrix_of_integers_from_string(encrypted_msg)
msg_len = int(len(encrypted_msg) / 2)
decrypted_msg = ""
for i in range(msg_len):
column_0 = P[0][i] * C_inverse[0][0] + P[1][i] * C_inverse[0][1]
integer = int(column_0 % 26 + 65)
decrypted_msg += chr(integer)
column_1 = P[0][i] * C_inverse[1][0] + P[1][i] * C_inverse[1][1]
integer = int(column_1 % 26 + 65)
decrypted_msg += chr(integer)
if decrypted_msg[-1] == "0":
decrypted_msg = decrypted_msg[:-1]
return decrypted_msg
def find_multiplicative_inverse(determinant):
multiplicative_inverse = -1
for i in range(26):
inverse = determinant * i
if inverse % 26 == 1:
multiplicative_inverse = i
break
return multiplicative_inverse
def make_key():
determinant = 0
C = None
while True:
cipher = input("Input the 4 letter key: ")
C = create_matrix_of_integers_from_string(cipher)
determinant = C[0][0] * C[1][1] - C[0][1] * C[1][0]
determinant = determinant % 26
inverse_element = find_multiplicative_inverse(determinant)
if inverse_element == -1:
print("Determinant is not relatively prime to 26, uninvertible key")
elif np.amax(C) > 26 and np.amin(C) < 0:
print("Only a-z characters are accepted")
print(np.amax(C), np.amin(C))
else:
break
return C
def create_matrix_of_integers_from_string(string):
integers = [chr_to_int(c) for c in string]
length = len(integers)
M = np.zeros((2, int(length / 2)), dtype=np.int32)
iterator = 0
for column in range(int(length / 2)):
for row in range(2):
M[row][column] = integers[iterator]
iterator += 1
return M
def chr_to_int(char):
char = char.upper()
integer = ord(char) - 65
return integer
def decryptor():
msg = input("Enter the encrypted message here: ")
decrypted_msg = decrypt(msg)
print("The plaintext is:",decrypted_msg)