Home > Net >  Caesar Cipher Not Encrypting
Caesar Cipher Not Encrypting

Time:01-20

Not sure why my code is not encrypting the cipher properly For example: "Hello how are you" is "2z669 29g vbz i9e" and my code will decrypt it just fine. If I attempt to encrypt it I get: "e]z } g vbz I e". I am assuming it has to do with the 21 modulus len(ALPHABET) I just figured if the decrypt is subtract I need to add to reverse the cipher, but I guess I am wrong any assistance would be appreciated thanks!

ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789."

def encrpytstr(message):
    newString = ''
    #loop to assign new alphabet value
    for index in range(0, len(message)):
        oneLetter = message[index]
        
        #assinging new alphabet value
        newAlphabetValue = (ALPHABET.find(oneLetter.lower())   21) % len(ALPHABET)   (ord('A') if oneLetter.isupper() else ord('a'))
        
        #checking for white spaces
        if oneLetter == ' ':
            newAlphabetValue = 32
        
        #creating the new string
        newString = newString   chr(newAlphabetValue)
    
    return newString


def decrpytstr(message):
    newString = ''
    #loop to assign new alphabet value
    for index in range(0, len(message)):
        oneLetter = message[index]
        
        #assinging new alphabet value
        newAlphabetValue = (ALPHABET.find(oneLetter.lower()) - 21) % len(ALPHABET)   (ord('A') if oneLetter.isupper() else ord('a'))
        
        #checking for white spaces
        if oneLetter == ' ':
            newAlphabetValue = 32
        
        #creating the new string
        newString = newString   chr(newAlphabetValue)
    
    return newString


def main():
    message = input("Enter text: ")
    choice = input("(E)ncrypt or (D)ecrypt?: ").upper()
    
    if choice == "E":
        encrpytstr(message)
        newString = encrpytstr(message)
        print(newString)
        input("Press ENTER to exit")
    
    elif choice == "D":
        decrpytstr(message)
        newString = decrpytstr(message)
        print(newString)
        input("Press ENTER to exit")
    
    else:
        print("Invalid Input Try Again!")
        input("Press ENTER to exit")
main()

CodePudding user response:

Adding a couple of print statements reveals a rather fundamental problem with your logic.

        #assinging new alphabet value
        newAlphabetValue = (ALPHABET.find(oneLetter.lower())   21) % len(ALPHABET)   (ord('A') if oneLetter.isupper() else ord('a'))
        print("input: %s new: %s" % (oneLetter, chr(newAlphabetValue)))
        print("(found %i  21 %i)" % (ALPHABET.find(oneLetter.lower()), ALPHABET.find(oneLetter.lower()) 21))

produces

input: H new: ]
(found 7  21 28)
input: e new: z
(found 4  21 25)
input: l new: 
(found 11  21 32)
input: l new: 
(found 11  21 32)
input: o new: „
(found 14  21 35)
input: , new: u
(found -1  21 20)
input:   new: u
(found -1  21 20)
input: h new: }
(found 7  21 28)
input: o new: „
(found 14  21 35)
input: w new: g
(found 22  21 43)
input:   new: u
(found -1  21 20)
input: a new: v
(found 0  21 21)
input: r new: b
(found 17  21 38)
input: e new: z
(found 4  21 25)
input:   new: u
(found -1  21 20)
input: y new: i
(found 24  21 45)
input: o new: „
(found 14  21 35)
input: u new: e
(found 20  21 41)
input: ? new: u
(found -1  21 20)

Notice how the result from find is often -1 and how this throws everything off?

I'm not sure exactly what's wrong because it's not clear how you thought this should work. Perhaps simplify the code so that it's more obvious what's going on and why.

The detour via the index is also quite unnecessary; Python is perfectly capable of looping over the items in a list directly. As an aside, probably avoid repeatedly appending stuff to the end of a string if you can.

def encrpytstr(message):
    # Use a list for speed
    newletters = []
    for letter in message:
        upcase = letter.isupper()
        letter = letter.lower()
        index = ALPHABET.find(letter)
        if index > -1:
            newindex = (index   21) % len(ALPHABET)
            # print("input: %s (%i, %i) new: %s (%i, %i)" % (letter, index, ord(letter), ALPHABET[newindex], newindex, ord(ALPHABET[newindex])))
            letter = ALPHABET[newindex]
            if upcase:
                letter = letter.upper()
        newletters.append(letter)
    # now finally do a slow string join
    return ''.join(newletters)

I left a commented-out print statement in case you want to repeat the debugging step with the new code.

The new code simply preserves verbatim any characters not in ALPHABET; it should be easy to see what to change if you don't want that.

Finally, did you misspell "encrpyt" and "decrpyt" on purpose? It's slightly humorous when you first see it, but will bite you in the back side once your code grows. Avoid weird misspellings in function names.

  •  Tags:  
  • Related