简体   繁体   中英

python - Caesar cipher - decryption of string using ord() and chr()

Ceasar cipher encryption method. Using ord() and chr () to decrypt a string. If a value with the offset is < 32 or > 126 on the ASCII table it will loop back around to the appropriate value.

However, it is not working 100%, skips over symbols from the ASCII table for some reason, and isn't getting every value correct?

input - yohvldvk#wioH#$

offset - 5

expected output - tjcqg_qf}rdjC}~

user_decrypt_message = input("Please enter string to decrypt: ")
decrypted_message = ""
user_decrypt_offset = 0

while not user_decrypt_offset in range (1, 95):
    user_decrypt_offset = int(input("Please enter offset value (1 to 94): "))

for letter in user_decrypt_message:
    if ord(letter) + user_decrypt_offset < 32:
        decrypted_message += chr(ord(letter) - user_decrypt_offset + 95)
    elif ord(letter) + user_decrypt_offset > 126:
        decrypted_message += chr(ord(letter) + user_decrypt_offset - 95)
    else:
        decrypted_message += chr(ord(letter) - user_decrypt_offset)

print()
print("Decrypted string: ")
print(decrypted_message)
def inputOffset():
    user_decrypt_offset = 0
    while user_decrypt_offset < 1 or user_decrypt_offset >= 95:
        user_decrypt_offset = int(input("Please enter offset value (1 to 94): "))
    return user_decrypt_offset
    
def decrypt(iuser_decrypt_message, user_decrypt_offset):
    decrypted_message = ""
    for letter in iuser_decrypt_message:
        if ord(letter) + user_decrypt_offset < 32:
            print("1. if", ord(letter))
            decrypted_message += chr(ord(letter) - user_decrypt_offset + 95)
        elif ord(letter) + user_decrypt_offset > 126:
            print("2. if", ord(letter))
            decrypted_message += chr(ord(letter) + user_decrypt_offset - 95)
        else:
            print("3. if", ord(letter))
            decrypted_message += chr(ord(letter) - user_decrypt_offset)
        print(decrypted_message, ord(decrypted_message[-1]))
    return decrypted_message
    
iuser_decrypt_message = input("Please enter string to decrypt: ")
user_decrypt_offset = inputOffset()
decrypted_message = decrypt(iuser_decrypt_message, user_decrypt_offset)

print()
print("Decrypted string: ")
print(decrypted_message)

I just rewrote your code and added a few print statements. If you run this code you will see that when the loop inside decrypt() function come to '#'(whose ASCII value is 35) it will jump to 3. if statement and it will append a character with ASCII value 30(35 - 5) which is ␞(record separator delimiter). I guess there is a problem with it because it won't display.

The problem is that your code is not consistent in subtracting the offset. Sometimes it adds it, sometimes it subtracts it. It should always do the same thing.

To avoid this mistake, first calculate the new offset, put it in a variable, and only work with that name from then onwards.

So:

for letter in user_decrypt_message:
    # Subtract the offset (never add it)
    new_offset = ord(letter) - user_decrypt_offset
    if new_offset < 32:
        decrypted_message += chr(new_offset + 95)
    elif new_offset > 126:
        decrypted_message += chr(new_offset - 95)
    else:
        decrypted_message += chr(new_offset)

It may be useful to work with the modulo operator:

for letter in user_decrypt_message:
    new_offset = (ord(letter) - user_decrypt_offset - 32) % 95 + 32
    decrypted_message += chr(new_offset)

And you can also build the string via a list comprehension:

decrypted_message = "".join(
    chr((ord(letter) - user_decrypt_offset - 32) % 95 + 32)
    for letter in user_decrypt_message
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM