Hill_cipher in python
Sun, Jun 14, 2020
1-minute read
This is a simple approach to coding the hill cipher.
import numpy as np
from pprint import pprint
def matrixinvmod26(M):
Minv = np.linalg.inv(M)
Mdet = np.linalg.det(M)
Mod26invTable = {}
for m in range(26):
for n in range(26):
if (m*n)%26==1:
Mod26invTable[m] = n
# print(m,n)
Mdet26 = Mdet%26
if Mdet26 in Mod26invTable:
Mdetinv26 = Mod26invTable[Mdet26]
else:
Mdetinv26 = None
Madj = Mdet*Minv
Madj26 = Madj%26
Minv26 = (Mdetinv26*Madj26)%26
Minv26 = np.matrix.round(Minv26, 0)%26
return Minv26
def hill_enc(M, plaintext):
plaintext = plaintext.replace(" ","")
plaintext = plaintext.lower()
while len(plaintext) % 3 != 0:
plaintext = plaintext + "x"
char_list = [ord(c)-97 for c in plaintext]
cit=[]
for i in range(0,len(char_list),3):
sublist = char_list[i:i+3]
mat_mul = np.matmul(M,sublist) % 26
mult_res = [chr(i+97) for i in mat_mul]
cit=cit+mult_res
c=''.join(cit)
return c
def hill_dec(M, ciphertext):
ciphertext = ciphertext.replace(" ","")
ciphertext = ciphertext.lower()
Minv = matrixinvmod26(M)
Minv = Minv.astype(int)
char_list = [ord(c)-97 for c in ciphertext]
pla=[]
for i in range(0,len(char_list),3):
sublist = char_list[i:i+3]
mat_mul = np.matmul(Minv,sublist) % 26
mult_res = [chr(i+97) for i in mat_mul]
pla=pla+mult_res
p=''.join(pla)
return p
def main():
plaintext2 = "plaintext"
ciphertext2 = "atakvninz"
M = np.array([[17,17,5],[21,18,21],[2,2,19]])
cipher = hill_enc(M,plaintext2)
print(cipher)
decipher = hill_dec(M,ciphertext2)
print(decipher)
if __name__=="__main__":
main()