I am fairly new to Python and I am trying to implement the Hill Cipher as a small project. I think I have the logic figured out and have got the encryption part to work, however, in the decryption part, I am facing troubles. Especially with the modulus operator. In the decrypt function below, the second from last line is what is giving troubles.
import numpy as np
import fractions as fr
def decrypt(matrix, words):
matrix=np.asmatrix(matrix)
length = len(matrix)
det_matrix=int(round((np.linalg.det(matrix))%26))
mult_inv=(abs(det_matrix*26)/fr.gcd(det_matrix,26))/26
matrix_inv=(((np.linalg.inv(matrix)*np.linalg.det(matrix))%26)*mult_inv)%26
words = words.lower()
arr = np.array([ord(i) - ord('a') for i in words], dtype=int)
decrypt_matrix=(np.asmatrix(matrix_inv)*(np.asmatrix(arr).transpose()))%26
return decrypt_matrix
My input to the decrypt function is:
>>> matrix
[[6, 24, 1], [13, 16, 10], [20, 17, 15]]
>>> words
'poh'
and after the calculation of det_matrix
, mult_inv
variable will have the value 25. So the line of code that calculates matrix_inv
will have the below value, (which is absolutely correct):
>>> matrix_inv
array([[ 8., 5., 10.],
[ 21., 8., 21.],
[ 21., 12., 8.]])
The array arr
will have the value:
>>> arr
array([15, 14, 7])
The problem now is the next line of code, before performing the modulus the result of the expression
matrix_inv*(np.asmatrix(arr).transpose())
is:
matrix([[ 260.],
[ 574.],
[ 539.]])
And now, if I perform modulus 26 on the above matrix, I should get the output as
([[0.],[2.],[19.]])
However, below is what I get when I execute the expression
>>> (np.asmatrix(matrix_inv)*(np.asmatrix(arr).transpose()))%26
matrix([[ 26.],
[ 2.],
[ 19.]])
I don't understand why the first element has been calculated incorrectly (260%26 is 0 and not 26)! However, the remaining two elements have been computed correctly!
Any help on this is much appreciated!!
P.S : I have tried running the code on versions 2.7.11 and 3.6.1. Does not work on either.