0

I understand modular arithmetic in its basic mathematical form for example:

38 = 2 mod 12

However in the following encryption and decryption code example it is used along with other math and I don't understand what it is used for.

def encrypt(key, msg):
    encryped = []
    for i, c in enumerate(msg):
        key_c = ord(key[i % len(key)])
        msg_c = ord(c)
        encryped.append(chr((msg_c + key_c) % 127))
    return ''.join(encryped)

def decrypt(key, encryped):
    msg = []
    for i, c in enumerate(encryped):
        key_c = ord(key[i % len(key)])
        enc_c = ord(c)
        msg.append(chr((enc_c - key_c) % 127))
    return ''.join(msg)

if __name__ == '__main__':
    key = 'This_is_my_awsome_secret_key'
    msg = 'Hello world'
    encrypted = encrypt(key, msg)
    decrypted = decrypt(key, encrypted)

    print 'Message:', repr(msg)
    print 'Key:', repr(key)
    print 'Encrypted:', repr(encrypted)
    print 'Decrypted:', repr(decrypted)

Can someone explain it to me please?

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Welcome to Stack! It's polite to give feedback and to accept and answer as well. – T.Woody Oct 21 '14 at 22:20
  • You don't have to put the language in the title at stackoverflow, as long as it is present as a tag. Please keep the title as short as possible. And a welcome from me too, of course :) – Maarten Bodewes Oct 21 '14 at 23:39
  • Thanks for the welcome and thank you for the advice ill keep it in mind for the future. I apologize for not giving feedback or accepting an answer, I have been having problems with my PC. – Thomas Hopkins Nov 07 '14 at 22:58

3 Answers3

1

in the parts key_c = ord(key[i % len(key)])

The % is used to avoid an IndexError - it just wraps the key around the message when the key is shorter than the message.

In encryped.append(chr((msg_c + key_c) % 127))

The % is used to keep the resulting chr in the 7-bit ascii range.

Think about % here like the clock: when it's x hours later than y 'o clock, it's (x+y) % 12 'o clock.

On a side note: I think it must be obvious, I want to mention it nonetheless: this "cipher" is of course far away from being secure.

ch3ka
  • 11,792
  • 4
  • 31
  • 28
  • Sorry I didn't get back to you straight away I have been having problems with my PC. Is there a way of making it more secure? – Thomas Hopkins Nov 07 '14 at 22:50
  • Nope. This is secure if and only if you are using a completely random key which is at least as long as the message, and is never used again. – ch3ka Nov 11 '14 at 13:23
0

The mod operator can be used in many different ways. In this case, it is used to constrain certain values and to make them "rotate". Example:

>>> a = [0,1,2,3,4,5]
>>> f = lambda x : (x + 4) % 6
>>> print map(f,a)
[5, 0, 1, 2, 3, 4]

As shown here, the function f adds 4 to each index and computes x mod 6 for all the resulting values, yielding an array which effectively has the same values moved 4 places to the right in a circular manner. In many cases, if we call x mod n, we are saying that we want the values to lie between 0 and n-1. This is often used in hashing functions and other functions where we need some large integers to map to a list index, no larger than the length of the list.

Dith
  • 151
  • 8
0

The modular of 127 us to ensure you stay in ASCII bounds (basically so it's readable). The modular for encrypted just makes a set up that can be undone, and appear random. However, given the keys simplicity, the encrypt can easily be undone the same way it was done.

I would recommend changing the key to just 'key', and write down the steps of encrypt, then decrypt. The pattern will be obvious after that. If you have any questions, feel free to ask.

T.Woody
  • 1,142
  • 2
  • 11
  • 25