I'm working on a Caesar Cypher project. I take the user's input, turn it into a list, take out spaces, and then encrypt the letters.
My question is: How do I re-add these spaces into the final encrypted message?
Here's what I have achieved so far (pretend word = message)
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']
en_de = input("Do you want to encrypt or decrypt your message? ")
word = input("Enter a word: ")
shift = input("Enter a number: ")
word = list(word)
indexes = []
def encrypt():
for letters in word:
if letters in alphabet:
index = (alphabet.index(letters))
int(index)
indexes.append(index)
print(indexes)
n = 0
n = n int(shift)
for i in range(len(indexes)):
indexes[i] = indexes[i] n
print(indexes)
ceaser_cipher = ''
for i in indexes:
if i > len(alphabet)-1:
i %= len(alphabet)
ceaser_cipher = ceaser_cipher (alphabet[i])
for
print(ceaser_cipher)
def decrypt():
for letters in word:
index = (alphabet.index(letters))
int(index)
indexes.append(index)
print(indexes)
n = 0
n = n int(shift)
for i in range(len(indexes)):
indexes[i] = indexes[i] - n
print(indexes)
ceaser_cipher = ''
for i in indexes:
if i > len(alphabet)-1:
i %= len(alphabet)
ceaser_cipher = ceaser_cipher (alphabet[i])
print(ceaser_cipher)
if en_de == "encrypt":
encrypt()
elif en_de == "decrypt":
decrypt()
CodePudding user response:
The structure I would go for, is like this:
input_string = input("Enter message or cipher: ")
input_list = input_string.split(" ")
# input_list will be a list of each word in input_string
# encrypt each word in input_list and append each encrypted word
# to a new list, let's say that list is called output_list
output = " ".join(output_list)
# output will be a string of each item in the list separated by spaces
The final program could look something like this:
alphabet = list("abcdefghijklmnopqrstuvwxyz")
message = input("message or cipher: ").lower().split(" ")
shift = int(input("shift: "))
shifted_alphabet = alphabet[shift:] alphabet[:shift]
cipher_list = []
for word in message:
cipher_word = ""
for letter in word:
cipher_word = shifted_alphabet[alphabet.index(letter)]
cipher_list.append(cipher_word)
print(" ".join(cipher_list))
CodePudding user response:
You are in the right path in your learning, and @Toby's answer is a good contribution for you.
I'd like to just tease you here and let you know that the whole "Caesar Cipher" can be fully implemented in a one-liner, once you get familiar with many other Python features and syntax.
Check this:
''.join(chr(a (i - a shift) % 26) if (a := 65) <= (i := ord(c)) <= 90 or (a := 97) <= i <= 122 else c for c in word)
Examples:
cipher = lambda w, s: ''.join(chr(a (i - a s) % 26) if (a := 65) <= (i := ord(c)) <= 90 or (a := 97) <= i <= 122 else c for c in w)
word = 'Hello, beautiful World!'
print(cipher(word, 4)) # positive shift
# Lipps, fieyxmjyp Asvph!
word = 'Lipps, fieyxmjyp Asvph!'
print(cipher(word, -4)) # -4 shift means decipher a 4 shift
# Hello, beautiful World!
Explanation:
''.join(seq)
takes a sequence of stringsseq
and concatenate them together into one string;ord(c)
gives index of the characterc
in the Unicode table. For example,ord('a')
returns the integer97
andord('A')
returns the integer65
;chr(i)
is the inverse oford
: It gives the character at indexi
in the Unicode table. For example,chr(122)
returns the string'z'
andchr(90)
returns the string'Z'
;... for c in word
is a generator expression. Is a nice compact and efficient idiom for creating a sequence from another sequence. In this case, I am taking every characterc
in the stringword
, performing an operation, and creating a new sequence with each resulting element.... if ... else ...
is the ternary operator. It is a shortcut to embed a condition in an expression. Here, if the character index is not between 65 and 90 (uppercase letters) or between 97 and 122 (lowercase letters), I am returning the same characterc
untouched. That makes any non-letter not get transformed by the cipher (like space, comma, or exclamation mark);x <= y <= z
is a chained comparisson, it is a nice idiom available in python that resembles the Math conditional expression.(a := 65)
and(i := ord(c))
make use of the walrus operator :=, aka "assignment expression". With this, you can assign a variable at the same time you use it in an expression, and this variable will be available for use in the enclosed context after the declaration. For example,i
is assigned in the left side of theor
operator, and is used in the right side. Also,a
is assigned in the "test" part of the conditional and used in the "expression" part.chr(a (i - a shift) % 26)
is performing a modulo operation with the python's operator %, where26
is the count of letters from A to Z. That means, if yourshift
makes your letter overflow the alphabet, it circles back to the beginning/end. For example,'B'
with a shift of-4
gives'X'
, and'x'
with a shift of30
gives'b'
(because30 = 26 4
);
It is a rather contrived implementation, but hopefully you got to know some new stuff today on python!