-1

I want to build a very simple encryption algorithm which transforms a char into another depending on a key-value. e.g. 'abc' with key- value of 2 would be -> 'cde'. My code is basicly working, but the problem is that it doesnt iterate around the lowercase alphabet ('z' with keyvalue 1 should be 'a' again). I also want the results to be a string. Hope anyone can help me out with this!! :)

def encrypt(message, key):
    message = message.lower().replace(" ", "")
    print("lower case message: " + message)



    for i in message:
         print(chr(ord(i) + key))

encrypt('abc', 1)
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Have you actually tried to add wrap around of the alphabet, or to convert your results to a single string? What specific problem did you struggle with when solving this? – MisterMiyagi Mar 12 '20 at 13:11
  • Does this answer your question? [Caesar Cipher issue](https://stackoverflow.com/questions/26369035/caesar-cipher-issue) – Błotosmętek Mar 12 '20 at 13:12
  • 1
    Does the algorithm need to support capital letters? What about whitespace and punctuation? What about non-ascii? What should "A Møøse once bit my sister!" become? – Kevin Mar 12 '20 at 13:18
  • Does this answer your question? [Caesar Cipher Function in Python](https://stackoverflow.com/questions/8886947/caesar-cipher-function-in-python) – MisterMiyagi Mar 12 '20 at 13:19

3 Answers3

0

You can use the modulo operator ('%') to get the rest after a division i.e. 10%3 would be 1. You can use this to make your values "wrap around" at a specific point.

I've moved your calculations out to two separate statements to make it clearer what's happening - first we find the value for the actual character (a => 0, b => 1, c => 2, etc) by subtracting 97 from the char value. We then add the key, and make sure that it wraps around at 26 (since there are only 26 lowercase letters in the english alphabet). We then add 97 again to get the proper ascii value of that letter again.

'z' will first be 122, subtracting 97 gives us 25, adding 1 gives us 26. Using the modulo operator, this tells us the rest would have been 0 - effectively wrapping around to a again. We get the character back by adding 97 to 0 - getting 97 - which is the ascii value of a.

To return the complete string, we add each character to the result by using +=. That way we can append each letter the the previous sequence of letters before returning them.

def encrypt(message, key):
    message = message.lower().replace(" ", "")
    print("lower case message: " + message)
    result = ""

    for i in message:
        offset_from_a = (ord(i) - 97) + key
        chr_value = 97 + (offset_from_a % 26)
        result += chr(chr_value)

    return result

encrypt('abc', 1) => 'bcd'
encrypt('zbc', 1) => 'acd'
MatsLindh
  • 49,529
  • 4
  • 53
  • 84
  • Hey thanks for your detailed help! The modulo really helped me to understand the issue! However i still have the problem that i cant print the result as a string. i tried print(str(result)) – ZauberPony Mar 12 '20 at 14:06
  • `result` is only available internally in the function. To print the returned value, use `encrypted = encrypt('abc', 1)` - and then `print(encrypted)` (you can use any other variable name than `encrypted` of course, but the important thing is that the name only exists outside of the function itself). – MatsLindh Mar 12 '20 at 14:11
  • ok then i think i have to solve it somehow else. the goal is to get a string from the function. is it possible to remove the return and just write print(str(result)) instead? – ZauberPony Mar 12 '20 at 14:26
  • The function gives you a string. I'm not sure what more you need :-) – MatsLindh Mar 12 '20 at 14:30
  • i dont get any output from the function :( – ZauberPony Mar 12 '20 at 14:31
  • 1
    edit: stupid me haha found out what went wrong! anyway thanks for your help!! You helped a newbie like me alot! – ZauberPony Mar 12 '20 at 14:39
0

You can just add an if condition as follows:

for i in message:
    val=ord(i) + key
    if val>122:
        print(chr(val-26),end='')
    else:
        print(chr(val),end='')
Raghul Raj
  • 1,428
  • 9
  • 24
0

You should make sure to only process expected chars. translate could be used here:

collate = ''.join([chr(x) for x in range(ord('a'), ord('z')+1)])

def encrypt(message, key):
    key = key % len(collate)
    mapped = collate[key:] + collate[:key]
    trans = str.maketrans(collate, mapped)
    return message.lower().translate(trans)

Demo:

>>> encrypt('Abc,d ef', 2)
'cde,f gh'

Nice points: no need to remember ASCII codes, robust to non alpha input...

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252