Do not understand the error I am receiving?

54 Views Asked by At

I have this function that I have significantly simplified that calculates the multiplicative and additive keys for decrypting an affine cipher and it works in some cases but there is this one case where it is throwing me an error and I am unsure why. Here is my code:

def InverseMod(a, m):
    for i in range(1,m):
        if ( m*i + 1) % a == 0:
            return ( m*i + 1) // a
    return 'These are not co-prime.'

def decryption_keys_affine(p1, p2, C1, C2, AL):

    s = InverseMod(p1 - p2, AL) * (C1 - C2)

    r = (InverseMod(s, AL) * C2 - p2) % AL

    print("INV(S):", InverseMod(s, AL), "\n" + "R:", r)

When I give it this input, it outputs the correct answers which are 17 and 26:

>>> decryption_keys_affine(3, 20, 19, 20, 42)
INV(S): 17 
R: 26

When I give it this input though, it throws me this error:

>>> decryption_keys_affine(5, 20, 9, 26, 26)
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    decryption_keys_affine(5, 20, 9, 26, 26)
  File "C:\Users\Herman\Desktop\crypto_math_functions.py", line 96, in decryption_keys_affine
    r = (InverseMod(s, AL) * C2 - p2) % AL
TypeError: unsupported operand type(s) for -: 'str' and 'int'

It should output:

>>> decryption_keys_affine(5, 20, 9, 26, 26)
INV(S): 7 
R: 20
2

There are 2 best solutions below

0
Ijaz Ur Rahim On BEST ANSWER

In InverseMod() you putted a condition if those calculations are not prime return "A string". So that function returns a String and the r statement becomes like

r = ("String" * int - int) % int

Which is not correct

Either return 0 or do some if conditions to solve it

0
Brian Cain On

This function InverseMod returns different types for different cases. If you don't pass the if test in the loop or the loop doesn't execute, you return a string instead.

def InverseMod(a, m):
    for i in range(1,m):
        if ( m*i + 1) % a == 0:
            return ( m*i + 1) // a
    return 'These are not co-prime.'

In general, this kind of behavior should instead be modeled with an exception.

If it had, the failure mode would be more apparent.

def InverseMod(a, m):
    for i in range(1,m):
        if ( m*i + 1) % a == 0:
            return ( m*i + 1) // a
    raise  ValueError('"{}" and "{}" are not co-prime'.format(a, m))