Reputation: 33
So I'm in the middle of making a simple Caesar cipher for practice and I can't get it to decipher entire strings, just individual letters.
symbol_add
is the function in question.
Here's the code:
import re
alphabet = "abcdefghijklmnopqrstuvwxyz"
def cleanIt(clean):
global alphabet
s = re.sub('[^a-z]+', '?', str(clean))
return s
def symbol_add(symbol, key):
encryptedMsg = ""
for x in symbol:
position = alphabet.find(x)
newPosition = (position + key) % 26
newLetter = alphabet[nyPosisjon]
encryptedMsg += nyBokstav
return encryptedMsg
def cipher(data,key):
text = ""
if data in alphabet:
text += symbol_add(symbol=data,key=key)
return text
def main():
try:
msg = (input("Write the message you would like to encrypt\n"))
key = int(input("which key would you like to use?\n"))
cleanIt(clean=msg)
print(cipher(data=msg, key=key))
except ValueError:
print("Write a number!")
main()
I'm sure the solution is pretty simple, still learning.
Any help in how to solve this will be greatly appreciated!
Upvotes: 1
Views: 380
Reputation: 325
import re
alphabet = "abcdefghijklmnopqrstuvwxyz"
def cleanIt(clean):
global alphabet
s = re.sub('[^a-z]+', '?', str(clean))
return s
def symbol_add(symbol, key):
position = alphabet.find(symbol)
newPosition = (position + key) % 26
newLetter = alphabet[newPosition]
return newLetter
def cipher(data,key):
text = ""
for letter in data:
if letter in alphabet:
text += symbol_add(symbol=letter,key=key)
return text
def main():
try:
msg = (input("Write the message you would like to encrypt\n"))
key = int(input("which key would you like to use?\n"))
# Note: you need to assign msg to be equal to cleanIt(clean=msg).
# Just calling cleanIt(clean=msg) won't work, as strings
# are immutable in Python
msg = cleanIt(clean=msg)
print(cipher(data=msg, key=key))
except ValueError:
print("Write a number!")
main()
The main changes are:
for loop
was moved from symbol_add
to cipher
, so that symbol_add
gets called for each charactermain()
: cleanIt(clean=msg)
-> msg = cleanIt(clean=msg)
; the reason for this is that strings are immutable in Python, meaning that you need to reassign the variable msg
to essentially point to the new string.Output of this code:
Write the message you would like to encrypt
test
which key would you like to use?
1
uftu
Also, try to stick to a single naming convention; you have a function that follows camelCase
(cleanIt
) and another that follows snake_case
(symbol_add
). Try and name all functions in the same way. (The convention in Python is to use snake_case
for functions)
Upvotes: 2
Reputation: 51643
You can streamline your cipher method quite a bit if you fill a dictionary as lookup when entering the method. It contains the mapping based on the key
provided and maps your input characters to to the cipher-character.
Its much faster to look up in a dict then to .index()
into a string.
Using dict.get(key[,default])
allows to provide the '?'
for unknowns so you need no import re
and no preprocessing.
Read about dict.get()
: Why dict.get(key) instead of dict[key]?
Adding uppercase mapping to the chiffre is trivial as well based on the lower case ones:
alphabet = "abcdefghijklmnopqrstuvwxyz"
def cipher(data, key):
# in case you change alphabet
la = len(alphabet)
# get the default lookup
chiffre = { c:alphabet[(i+key)%la] for i,c in enumerate(alphabet) }
# create lookup for upper cases as well
chiffre.update( { c.upper():n.upper() for c,n in chiffre.items() } )
# supply ? for all unknowns, use the knowns where possible and return as string
return ''.join( (chiffre.get(c,"?") for c in data) )
def main():
try:
msg = (input("Write the message you would like to encrypt\n"))
key = int(input("which key would you like to use?\n"))
print(cipher(data=msg, key=key))
except ValueError:
print("Write a number!")
main()
Output:
Write the message you would like to encrypt
Hello World
which key would you like to use?
1
Ifmmp?Xpsme
Upvotes: 1