Reputation: 43
I'm currently working on a Caesar cipher program, and I basically typed up a list of the alphabets: alphabet = ['a','b','c','d',...]
Then asked the user for a word to encrypt, text = input('Enter your message')
and the shift amount, I figured I could set an empty string variable and then loop through (for loop) each letter to shift it.
But this is where I got stuck, how will I shift each letter in the input by the shift amount using the list?
I tried to loop through the input using the indexes of the list alphabet, but since had no idea what I was doing it didn't work.
Upvotes: 2
Views: 57
Reputation: 1663
I'm not sure I fully understand what you are asking, but if you are just trying to shift by a constant amount to make a Cesar cipher, then this is fairly straightforward, you could have done with this a string rather than a list as well. The main thing to think about is the wrapping, which we can do with modulus operator. Lets say you want to shift 3 places: So if the index + shift is less than 26, the modulo operation doesn't change anything 2 + 3 % 26 = 5 If index + shift is 26 or greater, the modulo operation wraps it around. 24 + 3 % 26 = 1
example = "zebra"
alphabet = ['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']
encrypted = ''
for char in example:
if char in alphabet:
i = alphabet.index(char)
j = (i + 3) % 26
encrypted += alphabet[j]
else:
encrypted += char
Upvotes: 0
Reputation: 381
Here's a generic implementation of the caesar-cipher, that should work for any shift amount, and any charset.
Feel free to get rid of the type hinting if you feel it hinders readability. I personally would prefer to have it though.
import string
from typing import Hashable, Iterable, Sequence, TypeVar
T = Hashable
def caesar_ciper(message: Iterable[T], k: int, charset: Sequence[T] = string.ascii_lowercase) -> Iterable[T]:
n = len(charset)
char_idx = dict(zip(charset, range(n)))
shift = lambda x: charset[(char_idx[x] + k) % n]
return map(shift, message)
message = 'abcxyz' # read from user
k = 3 # read from user
encoded = ''.join(caesar_ciper(message, k))
assert encoded == 'defabc'
Upvotes: 0