Search code examples
python-3.xencryptionbrute-forcecaesar-cipher

When decrypting caesar cipher via brute force, cannot print right attempts


I'm attempting to decrypt a caesar cipher via brute force. I can encrypt something fairly easily, and then I want the program to decrypt a message using brute force. What I want to happen is for python to print out all 26 shift values of the encrypted message. This is my code:

message = input("What message do you want to use: ")
shiftValue = int(input("What would you like to shift the message by: "))
encryptedMsg = ""

for character in message: 
    if character.isalpha() == True: 
        if character == character.lower():
            x = ord(character) - 97 
            x += shiftValue 
            x = x % 26  
            encryptedMsg += chr(x + 97) 
        else:
            x = ord(character) - 65
            x += shiftValue
            x = x % 26
            encryptedMsg += chr(x+65)
    else: 
        encryptedMsg += character

print(encryptedMsg)

def decrypt(encryptedMsg):
    i = 0
    shiftValue = 0
    while i < 26:                  
        attempt = ""
        for char in encryptedMsg:
            if char.isalpha() == True:
                x = ord(char) - 97
                x = x + shiftValue
                x = x % 26
                attempt += chr(x+97)
            else:
                attempt += char
            print(attempt)
            i += 1
            shiftValue += 1

decrypt(encryptedMsg)

Once I run this, I am given the following code on the python shell. Lets say the message variable is "My name is Daniel" and I use a shiftValue of 2. This is what is printed:

i
ib
ib 
ib s
ib sg
ib sgt
ib sgtm
ib sgtm 
ib sgtm s
ib sgtm sd
ib sgtm sd 
ib sgtm sd k
ib sgtm sd ko
ib sgtm sd koc
ib sgtm sd kocy
ib sgtm sd kocyv
ib sgtm sd kocyvd
z
zs
zs 
zs j
zs jx
zs jxk
zs jxkd
zs jxkd 
zs jxkd j
zs jxkd ju
zs jxkd ju 
zs jxkd ju b
zs jxkd ju bf
zs jxkd ju bft
zs jxkd ju bftp
zs jxkd ju bftpm
zs jxkd ju bftpmu

Solution

  • The last 3 lines of decrypt() are executed at every iteration of for char in encryptedMsg. This is wrong. You want to finish creating the decrypted string before you print it.

    Another problem is that your program doesn't handle uppercase characters properly. A quick fix would be to use lower() to convert everything to lowercase before processing it.

    Try this:

    def decrypt(encryptedMsg):
        i = 0
        shiftValue = 0
        while i < 26:                  
            attempt = ""
            for char in encryptedMsg.lower():
                if char.isalpha() == True:
                    x = ord(char) - 97
                    x = x + shiftValue
                    x = x % 26
                    attempt += chr(x+97)
                else:
                    attempt += char
            i += 1
            shiftValue += 1
            print(attempt)
    

    Edit:

    A more "pythonic" way of implementing loops is to use syntax like for x in range(y):. Also, if x == True can always be simplified to if x:. Here's a simplified version of your code with a single iterator variable (shiftValue):

    def decrypt(encryptedMsg):
        for shiftValue in range(26):
            attempt = ""
            for char in encryptedMsg.lower():
                if char.isalpha():
                    x = (ord(char) - 97 + shiftValue) % 26
                    attempt += chr(x+97)
                else:
                    attempt += char
            print(attempt)