0

I'm trying to make a Caesar cipher encryptor/decryptor in Python, by getting the ASCII index of a letter and adding/subtracting from it. However, it seems to be using Unicode instead because I get letters with accents instead of just English alphabet letters. For example, if I enter the word 'weasel' and encrypt it by 2, what I get is 'yÞĿƲȗʃ'. How do I use ASCII?

Here is my code:

    def manipulate(text, key, e_or_d):
        ciphertext = ''
        for i in text:
            asciiCode = ord(i)
            if e_or_d == 'e':
                key = ord(i) + key
            elif e_or_d == 'd':
                key = ord(i) - key
            newChar = chr(key)
            ciphertext += newChar
        if e_or_d == 'e':
                print('Here is your encrypted text: ')
        elif e_or_d == 'd':
            print('Here is your decrypted text: ')
        print(ciphertext)
    
    text = input('Enter text: ')
    e_or_d = input('Enter \'e\' for encryption or \'d\' for decryption: ')
    key = int(input('Enter encryption key: '))
    manipulate(text, key, e_or_d)

I used chr and ord here to turn an index into a character and identify the index of a character, respectively.

Sorry if this is incoherent and disorganised.

3
  • 1
    You are accumulating on key variable that arrives to the function. Try new_ord = ord(i) + key instead of key = ord(i) + key to keep key the same throughout i.e., what user supplied. Similar goes for decryption if. Commented May 7, 2021 at 10:38
  • another thing to note is a-z only range from 97-122, so case like manipulate("weasel", 4, "e") will give you unexpected result and you need to handle it. Commented May 7, 2021 at 11:10
  • You should probably read Joel Spolsky's The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excluses!) All Python 3 strings are Unicode strings; you just have to understand how Unicode is organized. In brief, the first 128 characters are the ASCII subset. Commented May 10, 2021 at 4:59

2 Answers 2

2

It is taking using ascii. You are increasing key by ord(i) for every iteration in the loop. So it is not constant. Use a new variable instead of key and it should work.

def manipulate(text, key, e_or_d):
    ciphertext = ''
    for i in text:
        asciiCode = ord(i)
        if e_or_d == 'e':
            temp = ord(i) + key
        elif e_or_d == 'd':
            temp = ord(i) - key
        newChar = chr(temp)
        ciphertext += newChar
    if e_or_d == 'e':
        print('Here is your encrypted text: ')
    elif e_or_d == 'd':
        print('Here is your decrypted text: ')
    print(ciphertext)

NOTE: I think using boolean values for e_or_d would be better. Also keep your variable names consistent, like using camel case only or using _ only.

Sign up to request clarification or add additional context in comments.

Comments

2

There are few things to notice:

  1. you are changing key in every loop while it should keep the same, so you need another variable to save result
  2. ord(a)-ord(z) range from 97-122, you may have unexpected result even after changing point 1, for example, manipulate("a", 1, "d") is ` and manipulate("z", 1, "e") is {, as they are out of range after manipulate.

I suppose the user will only input lowercase letter, if they will input uppercase letter or other character, extra checking is needed, here's the code changing just 2 points above:

def manipulate(text, key, e_or_d):
    ciphertext = ''
    if e_or_d == "e":
        step = 1
        action = "encrypted"
    elif e_or_d == "d":
        step = -1
        action = "decrypted"
    for i in text:
        # * step means + key in encryption and - key in decryption
        new_ord = ord(i) + (key * step)
        # check if new_ord is inside the range of a-z
        if 97 <= new_ord <= 122:
            new_char = chr(new_ord)
        else:
            # if new_ord > 122, it will - 26, elif new_ord < 97, it will + 26
            new_char = chr(new_ord - (26 * step))
        ciphertext += new_char
    print(f'Here is your {action} text: ')
    print(ciphertext)

text = input('Enter text: ')
key = int(input('Enter encryption key: '))
e_or_d = input('Enter \'e\' for encryption or \'d\' for decryption: ')
manipulate(text, key, e_or_d)

Output:

Enter text: weasel
Enter encryption key: 2
Enter 'e' for encryption or 'd' for decryption: e
Here is your encrypted text:
ygcugn

Enter text: a
Enter encryption key: 1
Enter 'e' for encryption or 'd' for decryption: d
Here is your decrypted text:
z

Enter text: z
Enter encryption key: 1
Enter 'e' for encryption or 'd' for decryption: e
Here is your encrypted text:
a

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.