Python Forum
Modulus operator giving incorrect result
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Modulus operator giving incorrect result
#1
Hello,

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=(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 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 not 0 and not 26!) However, the remaining two elements have been computed correctly!

I have tried running the code on versions 2.7.11 (2.7.11 (v2.7.11:6d1b6a68f775, Dec 5 2015, 20:32:19) [MSC v.1500 32 bit (Intel)]) and 3.6.1 (3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)]). Does not work on either.

Any help on this is much appreciated!!
Reply
#2
Beware of floating point, numbers may not be what they seem to be:

With "integer" values:
Output:
>>> x=np.array([0.,26.,27.,260.]) >>> x array([   0.,   26.,   27.,  260.]) >>> x%26 array([ 0.,  0.,  1.,  0.])
Now let's use a slightly different value, such as the one you could get due to round-off errors. The display is the same:
Output:
>>> x=np.array([0.,26.,27.,260.-0.000000000001]) >>> x array([   0.,   26.,   27.,  260.])
But the result is different
Output:
>>> x%26 array([  0.,   0.,   1.,  26.])
because 10.*26. is greater than 260.-0.000000000001, so the quotient is 9:
Output:
>>> x//26 array([-0.,  1.,  1.,  9.])
and the rest is 25.99999999999 but displayed as 26.
Unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.
Your one-stop place for all your GIMP needs: gimp-forum.net
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  monthly composite of LST comes out incorrect, with error "mean of empty slices" ns423 1 2,886 Mar-18-2018, 06:40 PM
Last Post: ns423

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020