I have written a Caesar cipher with 2 parameters m and n,with characters to be shifted as follows:
It works fine as expected for encoding but not for decoding.
Below is my code.
def encode_cipher(n, m,message):
result = ""
p = m # Initialize p with the additional step shift 'm'
for char in message:
if char.islower():
# Determine the shift value for the current lowercase character
shift = n + p
# Adjust the shift to keep it within the range [0, 25]
shift = shift % 26
new_char = chr(((ord(char) - ord('a') + shift) % 26) + ord('a'))
result += new_char
# Update the value of p for the next character
p = ((ord(new_char) - ord('a')) % 26)
else:
# If the character is not a lowercase letter, leave it unchanged
result += char
return result
# Example usage for encoding
message = "aaaaaa"
n = 2
m = 2
encode_cipher( n, m,message)
#output is: "egikmo", as expected.
Now to decrypt, I have written the following:
def decode_cipher(n, m,message):
result = ""
p = m # Initialize p
for char in message:
if char.islower():
shift = n + p
shift = shift % 26
new_char = chr(((ord(char) - ord('a') - shift) % 26) + ord('a'))
result += new_char
# Update the value of p for the next character
p = ((ord(new_char) - ord('a')) % 26)
else:
result += char
return result
# Example
message = "egikmo" # Using output from encode function above.
n = 2
m = 2
decode_cipher( n, m,message)
The output is not "aaaaaa" i.e. the original message before encoding. So obviously subtracting the shift is not working and I wonder what I am missing.
==========================
EDIT:
After the comment.
To fix you decode
function according to your explanation in the comment, you'll simply need to change this line:
p = ((ord(new_char) - ord('a')) % 26)
with this:
p = ((ord(char) - ord('a')) % 26)
The difference is that you were using the index of the decoded character, instead of the character that weren't decoded.
==========================
For start, you meant to encrypt the first character with a shift of n + m, and you did that correctly. For all the other characters, you wanted to encrypt with a shift of n + the index of the former character, and that you failed to do.
I'll explain, the mistake is small, and located in this line:
p = ((ord(new_char) - ord('a')) % 26)
Instead of that, you should have just assigned the index of the current character.
To do that you need to get the index of the character along with the character, and one way to do that is iterate over a range in the length of the message, and obtain the character using the square brackets [index]
.
After updating the encode
function it would look like this:
def encode_cipher(n, m,message):
result = ""
p = m
for i in range(len(message)):
char = message[i]
if char.islower():
shift = n + p
shift = shift % 26
new_char = chr(((ord(char) - ord('a') + shift) % 26) + ord('a'))
result += new_char
p = i
else:
result += char
return result
Just to finish this answer, let's simply update the decode
function also:
def decode_cipher(n, m,message):
result = ""
p = m
for i in range(len(message)):
char = message[i]
if char.islower():
shift = n + p
shift = shift % 26
new_char = chr(((ord(char) - ord('a') - shift) % 26) + ord('a'))
result += new_char
p = i
else:
result += char
return result
Another thing: Because the difference between the functions is so minor, we can use the same function with a slight adjustment, it would look like this:
def my_cipher(n, m, message, decode=False):
result = ""
p = m
for i in range(len(message)):
char = message[i]
if char.islower():
shift = n + p
shift = shift % 26
if not decode:
new_char = chr(((ord(char) - ord('a') + shift) % 26) + ord('a'))
else:
new_char = chr(((ord(char) - ord('a') - shift) % 26) + ord('a'))
result += new_char
p = i
else:
result += char
return result
Best regards, and good luck with your project!