Программа Caesar Cipher работала, но сейчас не работает (помогите, пожалуйста) - Python 3

Я пишу код Цезаря Шифра для части контролируемой оценки. Я построил полностью функционирующую программу, и я подумал, что подозревал ее, но после изменения нескольких вещей я пошел, чтобы проверить, и все пошло не так!

Код довольно неопрятный, но я немного устал от кодирования этого сейчас и перешел в Интернет, чтобы узнать мнение других.

Код:

answer ="C"
while answer == "C":

    lettersList=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']

    def menu():
        userChoice=input("Would you like to encrypt or decrypt a message? E or D.\n").lower()
        while userChoice != "e" and userChoice != "d":
            print("Invalid.")
            userChoice=input("Would you like to encrypt or decrypt a message? E or D.\n").lower()
        print("\n")
        return userChoice

    def getPlaintext():
        plaintext= input("Please enter the message you would like encrypted/decrypted\n").lower()
        while plaintext.isalpha() == False:
            print("Invalid")
            plaintext=input("Please enter the message you would like encrypted/decrypted\n").lower()
        print("\n")
        return plaintext

    def getKey():
        key=int(input("Please enter a key. 1-26\n"))
        while key > 26 or key < 1:
            print("Invalid.")
            key=int(input("Please enter a key. 1-26\n"))
        print("\n")
        return key


    def encryptText(plaintext,key):
        characterNumber = 0
        newMessage = ""
        for characters in plaintext:
            character = plaintext[characterNumber]
            characterPosition = lettersList.index(character)
            newPosition=character+key
            newLetter = lettersList[newPosition]
            newMessage = (newMessage+newLetter)
            characterNumber= characterNumber+1
        print(newMessage)

    def decryptText(plaintext,key):
        characterNumber = 0
        newMessage = ""
        for characters in plaintext:
            character = plaintext[characterNumber]
            characterPosition = lettersList.index(character)
            print(characterPosition)
            newPosition=characterPosition-key
            newLetter = lettersList[newPosition]
            newMessage = (newMessage+newLetter)
            characterNumber= characterNumber+1
            newMessage = (newMessage.lower())
        print(newMessage)

    userChoice=menu()
    plaintext=getPlaintext()
    key=getKey()
    if userChoice == "e":
        encryptText(plaintext,key)
    elif userChoice == "d":
        decryptText(plaintext,key)
    print(newMessage)

2 ответа

Решение

В вашем коде есть несколько простых орфографических ошибок, которые мешают правильному функционированию. for characters in plaintext: должно быть for character in plaintext: - в своем коде вы создаете новую переменную characters который нигде не используется. Правильная функция шифрования с комментариями выглядит так:

def encryptText(plaintext, key):
    newMessage = ""
    for character in plaintext:  # 'character' holds each letter from 'plaintext'
        characterPosition = lettersList.index(character)
        newPosition = characterPosition + key  # shift the index, not the character!
        newLetter = lettersList[newPosition]
        newMessage = newMessage + newLetter  # append new letter to new message

    print(newMessage)

Чтобы это правильно работало на lettersList только с одним вхождением каждого символа (то есть длиной 26) вам нужно проверить, что смещенный индекс не выходит за пределы; то есть символ не больше 26. Если это так, то вычтите 26, как это

newPosition = characterPosition + key
if newPosition >= len(lettersList) then:
    newPosition -= len(lettersList)

или используйте оператор по модулю, как предложено. Это должно дать вам представление о том, как изменить функцию расшифровки так, чтобы она также "оборачивалась".

В decypryptText newPosition может быть отрицательным. В этом случае вы должны обернуть весь алфавит. Лучший способ сделать это - использовать оператор%:

newPosition = (characterPosition - key) % len(lettersList)

Между прочим, использование этого в encryptText также позволяет вам создавать в письмах lettersList только одну копию алфавита вместо двух копий, которые вы используете.

Есть и другие вещи, которые можно отшлифовать в этом коде, но они не так важны, как этот.

Редактировать: если вы хотите использовать заглавные буквы для decryptText, вы можете сделать decryptText просто вернуть newMessage.upper(). Таким же образом вы можете заставить encryptText возвращать newMessage.lower().

Другие вопросы по тегам