Search code examples
pythonpython-3.xfor-loopencryptionpython-idle

How to check for specific letters in string?


I am having a problem with my Python 3 encryption program. I am writing code that uses comparisons to check for certain letters in userMessage, using if statements, and for loops. The problem that I am having is that the alphabet pops up between each letter of the encrypted output. For example, if the output is supposed to be amxer, it is aAmBxCeDr. Also the second if statement that checks for vwxyz is making vwxyz pop up between the symbols that are encrypted from rolling vwxyz 5 times to the right in ASCII. The second if statement is to change those symbols into the letters abcde.

#Start
#variables
encryptedMessage=""
userMessage = input("your message here: ")
userMessage =userMessage.lower()
shift=5
#function
def step2():
    #for loop
    for character in userMessage:
        #5:50AM February 24th, 2020
        #looking for global variable
        global encryptedMessage
        if character== "a"or"b"or"c"or"d"or"e"or"f"or"g"or"h"or"i"or"j"or"k"or"l"or"m"or"n"or"o"or"p"or"q"or"r"or"s"or"t"or"u":
            eN = ord(character)
            eN+= shift
            encryptedMessage+=chr(eN)  
        #checking for letters that go to random symbols
        if character=="v"or"w"or"x"or"y"or"z":

            if character=="v": character=="a"
            if character=="w": character=="b"
            if character=="x": character=="c"
            if character=="y": character=="d"
            if character=="z": character=="e"
            encryptedMessage+=character

step2()
print(userMessage)
print(encryptedMessage)

My code has an output of:

your message here: abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
fagbhcidjekflgmhniojpkqlrmsntoupvqwrxsytzu{v|w}x~yz
>>> 

Solution

  • What you are using is an invalid syntax. character == 'a' or 'b' is same as (character == 'a') or 'b', which is alwaysTruesince'b' is not None`.

    If you want to use multiple equals, you have to write them out as character == 'a' or character == 'b' or ....

    Alternatively, much better solution (as shown below) is using set() and the in operator, which checks whether the character is inside the set, and returns True if it finds it.

    encryptedMessage=""
    userMessage = input("you'r message here: ")
    userMessage =userMessage.lower()
    shift=5
    #function
    FIRST= set(["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u"])
    SECOND = set(["v","w","x","y","z"])
    def step2():
        #for loop
        for character in userMessage:
            #5:50AM February 24th, 2020
            #looking for global variable
            global encryptedMessage
            if character in FIRST:
                eN = ord(character)
                eN+= shift
                encryptedMessage+=chr(eN)  
            #checking for letters that go to random symbols
            if character in SECOND:
                if character=="v": character=="a"
                if character=="w": character=="b"
                if character=="x": character=="c"
                if character=="y": character=="d"
                if character=="z": character=="e"
                encryptedMessage+=character
    
    step2()
    print(userMessage)
    print(encryptedMessage)
    

    And since i only now realised this is a simple rotation cypher, here is another example of how to implement this.

    Considering A to be 0, and Z to be 25, you can simple rotate using modular arithmetic as encrypted_char = (char + shift) % 26. In our case, the letters 'a' and 'z' are not on the number 1, but we can easily solve this by substracting, and then adding, the starting value

    A = ord('a')
    def lowercase_rotate_cypher( message, shift):
        accumulator = []
        for character in message:
            c = A + ( ( ord(character) + shift - A ) % 26)
            accumulator.append( chr(c) )
        return ''.join(accumulator)
    

    In your case, the shift=5 and message is passed from input.