I am learning to code through the introduction to computer science book written by John Zelle. I am stuck on exercise 5.8. I need to somehow modify this solution where the next character after "z" is "a" in order to make it circular. Any help would be great :)
def main():
print("This program can encode and decode Caesar Ciphers") #e.g. if key value is 2 --> word shifted 2 up e.g. a would be c
#input from user
inputText = input("Please enter a string of plaintext:").lower()
inputValue = eval(input("Please enter the value of the key:"))
inputEorD = input("Please enter e (to encrypt) or d (to decrypt) ")
#initate empty list
codedMessage = ""
#for character in the string
if inputEorD == "e":
for ch in inputText:
codedMessage += chr(ord(ch) + inputValue) #encode hence plus
elif inputEorD =="d":
codedMessage += chr(ord(ch) - inputValue) #decode hence minus
else:
print("You did not enter E/D! Try again!!")
print("The text inputed:", inputText, ".Is:", inputEorD, ".By the key of",inputValue, ".To make the message", codedMessage)
main()
Since you're dealing with .lower()-case letters, it's fair to know that their ASCII range is [97-122].
A good way to make the shifting circular would be to represent each letter with the range [0-25], which is done by ord(ch) - 97, and then add the key, then modulo the result with 26 so it becomes (ord(ch) - 97 + key)%26, we'll then have a result in range [0-25], adding 97 will then get it's ASCII code:
def main():
print("This program can encode and decode Caesar Ciphers")
inputText = input("Please enter a string of plaintext:").lower()
inputValue = int(input("Please enter the value of the key:")) # use int(), don't eval unless you read more about it
inputEorD = input("Please enter e (to encrypt) or d (to decrypt) ")
codedMessage = ""
if inputEorD == "e":
for ch in inputText:
codedMessage += chr((ord(ch) - 97 + inputValue)%26 + 97)
elif inputEorD =="d":
codedMessage += chr((ord(ch) - 97 - inputValue)%26 + 97)
else:
print("You did not enter E/D! Try again!!")
print("The text inputed:", inputText, ".Is:", inputEorD, ".By the key of",inputValue, ".To make the message", codedMessage)
main()
Related
So, I had 2 scripts, a Vigenere cipher and a Caesar cipher, however, when I decided to merge them into a "mainproject" file by using "import" to import the script after the wanted answer from the user is sent on the Terminal page, when I've done the code and decided to execute the mainproject, I've got the question whether to choose to use Vigenere or Caesar, once I typed caesar (1) it played the first 2-4 lines and stopped the code once I've encountered the "def" line on both of scripts, if thats the problem, I can't use imports with "def", how can I merge them both into one file that asks which script I would like to use?
Caesar:
import time
import sys
print("Welcome to Caesar Cipher")
time.sleep(3)
print("Choose the corresponding number to Encrypt or Decrypt in Caesar Cipher")
def encryption():
print("Encryption")
print("You have chose ENCRYPTION")
msg = input("Enter message: ")
key = int(input("Enter key(0-25): "))
encrypted_text = ""
for i in range(len(msg)):
if ord(msg[i]) == 32:
encrypted_text += chr(ord(msg[i]))
elif ord(msg[i]) + key > 122:
temp = (ord(msg[i]) + key) - 122
encrypted_text += chr(96+temp)
elif (ord(msg[i]) + key > 90) and (ord(msg[i]) <= 96):
temp = (ord(msg[i]) + key) - 90
encrypted_text += chr(64+temp)
else:
encrypted_text += chr(ord(msg[i]) + key)
print("Your Encrypted Message: " + encrypted_text)
def decryption():
print("Decryption")
print("You have chose DECRYPTION")
encrp_msg = input("Enter encrypted Text: ")
decrp_key = int(input("Enter key(0-25): "))
decrypted_text = ""
for i in range(len(encrp_msg)):
if ord(encrp_msg[i]) == 32:
decrypted_text += chr(ord(encrp_msg[i]))
elif ((ord(encrp_msg[i]) - decrp_key) < 97) and ((ord(encrp_msg[i]) - decrp_key) > 90):
temp = (ord(encrp_msg[i]) - decrp_key) + 26
decrypted_text += chr(temp)
elif (ord(encrp_msg[i]) - decrp_key) < 65:
temp = (ord(encrp_msg[i]) - decrp_key) + 26
decrypted_text += chr(temp)
else:
decrypted_text += chr(ord(encrp_msg[i]) - decrp_key)
print("Text has been Decrypted: " + decrypted_text)
choice = int(input("1. Encryption\n2. Decryption\nChoose(1,2): "))
if choice == 1:
encryption()
elif choice == 2:
decryption()
else:
print("Wrong Choice")
Vigenere:
import time
print("Welcome to Vigenere Cipher")
time.sleep(2)
print("Choose the corresponding number to Encrypt or Decrypt in Vigenere Cipher")
time.sleep(2.5)
def msg_and_key():
msg = input("Enter message: ").upper()
key = input("Enter key: ").upper()
key_map = ""
j=0
for i in range(len(msg)):
if ord(msg[i]) == 32:
key_map += " "
else:
if j < len(key):
key_map += key[j]
j += 1
else:
j = 0
key_map += key[j]
j += 1
return msg, key_map
def create_vigenere_table():
table = []
for i in range(26):
table.append([])
for row in range(26):
for column in range(26):
if (row + 65) + column > 90:
table[row].append(chr((row+65) + column - 26))
else:
table[row].append(chr((row+65)+column))
return table
def cipher_encryption(message, mapped_key):
table = create_vigenere_table()
encrypted_text = ""
for i in range(len(message)):
if message[i] == chr(32):
encrypted_text += " "
else:
row = ord(message[i])-65
column = ord(mapped_key[i]) - 65
encrypted_text += table[row][column]
print("Encrypted Message: {}".format(encrypted_text))
def itr_count(mapped_key, message):
counter = 0
result = ""
for i in range(26):
if mapped_key + i > 90:
result += chr(mapped_key+(i-26))
else:
result += chr(mapped_key+i)
for i in range(len(result)):
if result[i] == chr(message):
break
else:
counter += 1
return counter
def cipher_decryption(message, mapped_key):
table = create_vigenere_table()
decrypted_text = ""
for i in range(len(message)):
if message[i] == chr(32):
decrypted_text += " "
else:
decrypted_text += chr(65 + itr_count(ord(mapped_key[i]), ord(message[i])))
print("Decrypted Message: {}".format(decrypted_text))
print("Key and Message can only be alphabetic")
time.sleep(1.5)
choice = int(input("1. Encryption\n2. Decryption\nChoose(1,2): "))
if choice == 1:
print("You have chose ENCRYPTION")
message, mapped_key = msg_and_key()
cipher_encryption(message, mapped_key)
elif choice == 2:
print("You have chose DECRYPTION")
message, mapped_key = msg_and_key()
cipher_decryption(message, mapped_key)
else:
print("Wrong choice")
Any help would be appreciated!
def only defines a function. To actually execute it you need to call it.
It seems the following part should be outside of decryption function body i.e. indented to the left. It:
call be executed directly on the module level
can be a separate function e.g. main that you can call
As main:
def main():
choice = int(input("1. Encryption\n2. Decryption\nChoose(1,2): "))
if choice == 1:
encryption()
elif choice == 2:
decryption()
else:
print("Wrong Choice")
And now you can call the main function:
main()
Welcome to Stackoverflow. This answer ended up more as general advice than a specific point solution to your problem, but I hope it's helpful.
One obvious remark is that it would be nice not to have to import the code for the cypher you don't intend to use.
Imports are executable statements, so this is quite practical.
Your code is far from optimally organised. Much of the code on the two files is the same or very similar. This is not unusual for new programmers, as it takes a while to learn how to break problems down and extract the common elements. The real problem is that while it defines lots of functions, none of them actually get called (unless there's more code you haven't included).
I would recommend that you modify your code so that there's a top-level program that collects the key and data and performs the required operations, along with your two
encryption/decryption modules. The encryption and decryption routines shouldn't do any input or output at all, just deal with the data.
Let's assume you have a variable mtype that holds the type of encryption you want to use. The top-level logic could look something like this:
if mtype == "caesar":
from caesar import encrypt, decrypt
elif mtype == "vigniere":
from vigniere import encrypt, decrypt
else:
sys.exit("Unrecognised message type")
If this code succeeds you would then have an encrypt and a decrypt function from the correct module. This means that they have to have the same interface, since your logic must now be written to accommodate either.
The remainder of your logic would look something like this (untested):
operation = input("E(ncrypt) or D(ecrypt)? ")
if operation.upper().startswith("E"):
function = encrypt
elif operation.upper().startswith("D"):
function = decrypt
else:
sys.exit("Unknown operation")
message = input(...)
key = input(...)
output = function(message, key)
This will hopefully make your code clearer by separating out the I/O responsibility
from the encryption and decryption tasks.
I am trying to limit decryption in the bruteforcing stage (3) to between ASCII 32 and ASCII 126. I have succeeded in it during the first two stages, but I am having a little trouble with implementing it during bruteforcing so my results come back accurate. The desired output is:
*** Menu ***
1. Encrypt string
2. Decrypt string
3. Brute force decryption
4. Quit
What would you like to do [1,2,3,4]? 3
Please enter string to decrypt: ykixkz&yw{oxxkr
Offset: 1 = Decrypted string: xjhwjy%xvznwwjq
Offset: 2 = Decrypted string: wigvix$wuymvvip
Offset: 3 = Decrypted string: vhfuhw#vtxluuho
Offset: 4 = Decrypted string: ugetgv"uswkttgn
Offset: 5 = Decrypted string: tfdsfu!trvjssfm
Offset: 6 = Decrypted string: secret squirrel
Offset: 7 = Decrypted string: rdbqds~rpthqqdk
Offset: 8 = Decrypted string: qcapcr}qosgppcj
Offset: 9 = Decrypted string: pb`obq|pnrfoobi
Offset: 10 = Decrypted string: oa_nap{omqennah
as you can see, it needs to produce "secret squirrel".
In the bruteforcing, I do not know where to implement the
for char in stringEncrypt:
x = ord(char)
x = x + offsetValue
while x < 32:
x += 95
while x > 126:
x -= 95
total += chr(x)
so I can also achieve an output that decrypts from ASCII 32 to ASCII 126.
Any help would be appreciated.
I've tried making it into a while loop and also putting it in different places in the code.
print("*** Menu ***")
print(" ")
print("1. Encrypt string")
print("2. Decrypt string")
print("3. Brute force decryption")
print("4. Quit")
print(" ")
selection = int(input("What would you like to do [1,2,3,4]? "))
while selection == 1:
stringEncrypt = input("Please enter string to encrypt: ")
offsetValue = int(input("Please enter offset value (1 to 94): "))
total = ""
for char in stringEncrypt:
x = ord(char)
x = x + offsetValue
while x < 32:
x += 95
while x > 126:
x -= 95
total += chr(x)
print(" ")
print("Encrypted string:")
print(total)
print(" ")
print("*** Menu ***")
print(" ")
print("1. Encrypt string")
print("2. Decrypt string")
print("3. Brute force decryption")
print("4. Quit")
print(" ")
selection = int(input("What would you like to do [1,2,3,4]? "))
while selection == 2:
stringDecrypt = input("Please enter string to decrypt: ")
offsetValue = int(input("Please enter offset value (1 to 94): "))
total = ""
for char in stringDecrypt:
x = ord(char)
x = x - offsetValue
while x < 32:
x += 95
while x > 126:
x -= 95
total += chr(x)
print(" ")
print("Decrypted string:")
print(total)
print(" ")
print("*** Menu ***")
print(" ")
print("1. Encrypt string")
print("2. Decrypt string")
print("3. Brute force decryption")
print("4. Quit")
print(" ")
selection = int(input("What would you like to do [1,2,3,4]? "))
while selection == 3:
stringDecrypt = input("Please enter string to decrypt: ")
decryptList = list(stringDecrypt)
offsetValue = 0
decryptIndex = 0
for offsetValue in range(1, 95, 1):
for decryptIndex in range(len(decryptList)):
shifting = (ord(decryptList[decryptIndex]) - ord(" ") - offsetValue) % 95
chrDecrypt = chr(shifting + ord(" "))
decryptList[decryptIndex] = chrDecrypt
decryptIndex += 1
stringDecrypt = ''.join(decryptList)
print("Offset", offsetValue, " = Decrypted string:", stringDecrypt)
print(" ")
print("*** Menu ***")
print(" ")
print("1. Encrypt string")
print("2. Decrypt string")
print("3. Brute force decryption")
print("4. Quit")
print(" ")
selection = int(input("What would you like to do [1,2,3,4]?"))
if selection == 4:
print("Goodbye.")
I expect the output to be, entering ykixkz&yw{oxxkr:
Offset: 1 = Decrypted string: xjhwjy%xvznwwjq
Offset: 2 = Decrypted string: wigvix$wuymvvip
Offset: 3 = Decrypted string: vhfuhw#vtxluuho
Offset: 4 = Decrypted string: ugetgv"uswkttgn
Offset: 5 = Decrypted string: tfdsfu!trvjssfm
Offset: 6 = Decrypted string: secret squirrel
Offset: 7 = Decrypted string: rdbqds~rpthqqdk
Offset: 8 = Decrypted string: qcapcr}qosgppcj
Offset: 9 = Decrypted string: pb`obq|pnrfoobi
Offset: 10 = Decrypted string: oa_nap{omqennah
but instead I get:
Offset 1 = Decrypted string: xjhwjy%xvznwwjq
Offset 2 = Decrypted string: vhfuhw#vtxluuho
Offset 3 = Decrypted string: secret squirrel
Offset 4 = Decrypted string: oa_nap{omqennah
Offset 5 = Decrypted string: j\Zi\kvjhl`ii\c
Offset 6 = Decrypted string: dVTcVepdbfZccV]
Offset 7 = Decrypted string: ]OM\O^i][_S\\OV
Offset 8 = Decrypted string: UGETGVaUSWKTTGN
Offset 9 = Decrypted string: L><K>MXLJNBKK>E
Offset 10 = Decrypted string: B42A4CNB#D8AA4;
(Up to 94).
Note the difference between your char decryption at the decrypt function (x) and the brute force function (chrDecrypt). At the later, you do not make sure the character is looping correctly. This is where the condition should be, basically making sure you are looping on the values 32 to 128.
One way to implement it would be as follows:
shifting = (ord(decryptList[decryptIndex]) - ord(" ") - offsetValue) % 95
chrDecrypt = chr(shifting + ord(" "))
This will be a shifted module on the required char.
In order to deal with the overriding of the decryptList array, you can do the following:
...
tempDecrypt = []
for decryptIndex in range(len(decryptList)):
shifting = (ord(decryptList[decryptIndex]) - ord(" ") - offsetValue) % 95
chrDecrypt = chr(shifting + ord(" "))
tempDecrypt.append(chrDecrypt)
decryptIndex += 1
stringDecrypt = ''.join(tempDecrypt)
...
This will fix the change of order you noticed in the previous code.
TRY:
cipher_text = input("Enter the Cipher Text = ")
length = len(cipher_text)
plain_text = ""
i = 0
key = 1
while key < 26:
plain_text = ""
while i < length:
if ord(cipher_text[i]) - key < 32:
plain_text += chr(ord(cipher_text[i]) - key + 95)
else:
plain_text += chr(ord(cipher_text[i]) - key)
i += 1
i = 0
print("Decrypting cipher text with key ", key, "is", plain_text)
key += 1
OUTPUT:-
Enter the Cipher Text = ykixkz&yw{oxxkr
Decrypting cipher text with key 1 is xjhwjy%xvznwwjq
Decrypting cipher text with key 2 is wigvix$wuymvvip
Decrypting cipher text with key 3 is vhfuhw#vtxluuho
Decrypting cipher text with key 4 is ugetgv"uswkttgn
Decrypting cipher text with key 5 is tfdsfu!trvjssfm
Decrypting cipher text with key 6 is secret squirrel
Decrypting cipher text with key 7 is rdbqds~rpthqqdk
Decrypting cipher text with key 8 is qcapcr}qosgppcj
Decrypting cipher text with key 9 is pb`obq|pnrfoobi
Decrypting cipher text with key 10 is oa_nap{omqennah
Decrypting cipher text with key 11 is n`^m`oznlpdmm`g
Decrypting cipher text with key 12 is m_]l_nymkocll_f
Decrypting cipher text with key 13 is l^\k^mxljnbkk^e
Decrypting cipher text with key 14 is k][j]lwkimajj]d
Decrypting cipher text with key 15 is j\Zi\kvjhl`ii\c
Decrypting cipher text with key 16 is i[Yh[juigk_hh[b
Decrypting cipher text with key 17 is hZXgZithfj^ggZa
Decrypting cipher text with key 18 is gYWfYhsgei]ffY`
Decrypting cipher text with key 19 is fXVeXgrfdh\eeX_
Decrypting cipher text with key 20 is eWUdWfqecg[ddW^
Decrypting cipher text with key 21 is dVTcVepdbfZccV]
Decrypting cipher text with key 22 is cUSbUdocaeYbbU\
Decrypting cipher text with key 23 is bTRaTcnb`dXaaT[
Decrypting cipher text with key 24 is aSQ`Sbma_cW``SZ
Decrypting cipher text with key 25 is `RP_Ral`^bV__RY
P.S. The code that you provided isn't of Caesar cipher, it is of Modified Caesar cipher. The difference between the two is that Caesar cipher uses constant key (key = 3), but Modified Caesar cipher can use variable keys (0 < key < 26).
I would greatly appreciate your feedback on my first ever Python project! :D
Basically I am coding a Caesar Cipher and I think its pretty terribly 'optimised / efficient' if you know what I mean, this is because I copied and pasted the encrypt() method for the decrypt() method and the only thing I changes was instead of rotating the numbers more, I rotated them less. This is what I'm talking about:
newPosition = (abc.find(letter) - key) % 26
^^ Instead of having a + (plus) I made it a - (minus) ^^
Is there a way I can sort of call the encrypt() method at just the newPosition line? Or what I did was correct and it doesn't need fixing (which I highly doubt)
** Please do take in mind that I do not have much knowledge in Python (if any at all) since I just started today so don't blow my brain up with some super complex code. THANK YOU!!! **
abc = 'abcdefghijklmnopqrstuvwxyz'
def main():
message = input("Would you like to encrypt or decrypt a word?")
if message.lower() == "encrypt":
encrypt()
elif message.lower() == "decrypt":
decrypt()
else:
print("You must enter either 'encrypt' or 'decrypt'.")
main()
def encrypt():
message = input("Enter a message to encrypt: ")
message = message.lower()
key = int(input("What number would you like for your key value?"))
cipherText = ""
for letter in message:
if letter in abc:
newPosition = (abc.find(letter) + key) % 26
cipherText += abc[newPosition]
else:
cipherText += letter
print(cipherText)
return cipherText
def decrypt():
message = input("Enter a message to decrypt: ")
message = message.lower()
key = int(input("What number would you like for your key value?"))
cipherText = ""
for letter in message:
if letter in abc:
newPosition = (abc.find(letter) - key) % 26
cipherText += abc[newPosition]
else:
cipherText += letter
print(cipherText)
return cipherText
main()
In general, str.find is bad performance-wise. It's O(n) complexity, which isn't awful, but you rarely actually need it. In this case you can use ord to convert each letter to its ordinal, then subtract ord('a') to get 0-25 instead of 97-122.
This is particularly useful, because you can then use chr to convert back without needing a lookup.
for letter in message:
if letter in string.ascii_lowercase: # same as "abcdef..z"
new_position = ((ord(letter) - ord('a') + key) % 26) + ord('a')
new_ch = chr(new_position)
ciphertext += new_ch
Note also that concatenating strings with += isn't as fast as something like str.join.
new_letters = [chr(((ord(letter) - ord('a') + key) % 26) + ord('a')) if letter in ascii_lowercase else letter for letter in message]
ciphertext = "".join(new_letters)
And since that chr(((ord(letter) - ord('a') + key) % 26) + ord('a')) is so ugly, I'd refactor that into a function.
def rotate(letter, key=0):
c_pos = ord(letter) - ord('a')
rotated = c_pos + key
modded = rotated % 26
final_pos = modded + ord('a')
return chr(final_pos)
new_letters = [rotate(c, key) if c in string.ascii_lowercase else c for c in letters]
ciphertext = "".join(new_letters)
A point of maintainability: it's easier to write testably good code if you separate your inputs from your results. Right now you'd have to do some monkey patching of stdin to write unit tests for any of your functions, but if you move your requests for user input into main and out of their respective function, that gets much easier.
def main():
message = input("What's the message to encrypt/decrypt? ")
key = int(input("What number would you like for your key value? "))
choice = input("Choose: encrypt or decrypt. ")
if choice == "encrypt":
result = encrypt(message, key)
elif choice == "decrypt":
result = decrypt(message, key)
else:
# something here about a bad user input.
In fact, when you consider the Caesar Cipher is reversible by flipping the sign of the key, you can simply do:
if choice == "encrypt":
result = encrypt(message, key)
elif choice == "decrypt":
result = encrypt(message, key * (-1))
and not write a decrypt function at all!
i've had a look through several python scripts for using an RC4 block cipher... i'm having issues completing the program so that it outputs properly...
Program currently asks for a "key" and "plaintext" (text to encrypt with key).
and outputs a encoded string... i think. so if i enter the word "Plaintext" to encrypt i get the following. however i think this is incomplete...
[187, 243, 22, 232, 217, 64, 175, 10, 211]
i want to have my encrypted output in hex
BB F3 16 E8 D9 40 AF 0A D3
my program is incomplete at the moment, but would just like some direction on how to
finish off the encryption part so it outputs as Hexadecimal (i think i have to convert bytes to hex?)
EDIT: The above has been resolved by Ebrahim. just need help with the decryption
i'm lost on where to begin with the decryption... i want to be able to have an input that will take a key and a ciphertext both in hexadecimal; and decrypt the ciphertext to plaintext.
I understand the logic in the encryption process, but i'm having trouble grasping the decryption process even though it is quite similar.
# Global variables
state = [None] * 256
p = q = None
def setKey(key):
##RC4 Key Scheduling Algorithm
global p, q, state
state = [n for n in range(256)]
p = q = j = 0
for i in range(256):
if len(key) > 0:
j = (j + state[i] + key[i % len(key)]) % 256
else:
j = (j + state[i]) % 256
state[i], state[j] = state[j], state[i]
def byteGenerator():
##RC4 Pseudo-Random Generation Algorithm
global p, q, state
p = (p + 1) % 256
q = (q + state[p]) % 256
state[p], state[q] = state[q], state[p]
return state[(state[p] + state[q]) % 256]
def encrypt(key,inputString):
##Encrypt input string returning a byte list
setKey(string_to_list(key))
return [ord(p) ^ byteGenerator() for p in inputString]
def decrypt(inputByteList):
##Decrypt input byte list returning a string
return "".join([chr(c ^ byteGenerator()) for c in inputByteList])
def intToList(inputNumber):
##Convert a number into a byte list
inputString = "{:02x}".format(inputNumber)
return [int(inputString[i:i + 2], 16) for i in range(0, len(inputString), 2)]
def string_to_list(inputString):
##Convert a string into a byte list
return [ord(c) for c in inputString]
loop = 1
while loop == 1: #simple loop to always bring the user back to the menu
print("RC4 Encryptor/Decryptor")
print
print("Please choose an option from the below menu")
print
print("1) Encrypt")
print("2) Decrypt")
print
choice = input("Choose your option: ")
choice = int(choice)
if choice == 1:
key = raw_input("Enter Key: ")
inputstring = raw_input("enter plaintext: ")
encrypt(key, inputstring)
elif choice == 2:
key = raw_input("Enter Key: ")
ciphertext = raw_input("enter plaintext: ")
print decrypt(intToList(ciphertext))
elif choice == 3:
#returns the user to the previous menu by ending the loop and clearing the screen.
loop = 0
else:
print ("please enter a valid option") #if any NUMBER other than 1, 2 or 3 is entered.
To convert your decimal output to hex output:
>>> arr = [187, 243, 22, 232, 217, 64, 175, 10, 211]
>>> ' '.join('%02x'%i for i in arr)
'bb f3 16 e8 d9 40 af 0a d3'
>>>
I know this is very old question, but here are some insigths just in case:
First RC4 is not a block cipher, is a stream cipher
Second, the decryption is exact the same as the encryption, as the algorithm generates the ciphertext by XORing the plaintext with some stream obtained using the key, and XOR is reversible, meaning: to decypher just need to XOR the ciphertext with the same generated stream.
Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
def menu():
choice = input("Press 1 to encode, 2 to decode, 9 to exit ")
return choice
def makeKeycode(message):
key = input("What is the key? ").upper()
length = len(message)
keycode = ""
counter = 0
while length >0:
if counter == len(key):
counter = 0
keycode = keycode + key[counter]
counter = counter + 1
length = length - 1
print(keycode)
return keycode
def enterMessage():
message = input("What is the message ").upper()
return message
def encodeMessage(message, keycode):
ciphertext =""
alphabet= "ABCDEFGHIJKLMNOPQRTUVWXYZ"
for i in range (len(message)):
character = message[i]
charCode = alphabet.find(character)
keycodeChar =keycode[i]
keyLetter = alphabet.find(keycodeChar)
position = (charCode + keyLetter)%25
cipherLetter = alphabet[position]
ciphertext =ciphertext + cipherLetter
return ciphertext
def decodeMessage(ciphertext,keycode):
ciphertext =""
alphabet= "ABCDEFGHIJKLMNOPQRTUVWXYZ"
for i in range (len(ciphertext)):
character = ciphertext[i]
charCode = alphabet.find(character)
keycodeChar =keycode[i]
keyLetter = alphabet.find(keycodeChar)
position = (charCode - keyLetter)%25
cipherLetter = alphabet[position]
ciphertext =ciphertext - cipherLetter
return message
def enterCipher ():
ciphertext = input("Enter the text to be decoded")
return ciphertext
def encode():
message = enterMessage()
keycode = makeKeycode(message)
ciphertext = encodeMessage(message,keycode)
print(ciphertext)
def decode():
keycode = makeKeycode(ciphertext)
message = decodeMessage(ciphertext, keycode)
print (message)
def main():
MyDictionary=("A:1","B:2","C:3","D:4","E:5","F:6","G:7","H:8","I:9","J:10","K:11","L:12","M:13","N:14","O:15","P:16","Q:17","R:18","S:19","T:20","U:21","V:22","W:23","X:24","Y:25","X:26")
print (MyDictionary)
choice = 0
while choice !=9:
choice = int(menu())
if choice == 1:
encode()
elif choice == 2:
decode()
if __name__ == "__main__":
main()
Hi, I cant get my code to work, my encode function works but i am struggling to fix my decode function. I dont understand where i am going wrong. I want to be able to decode the message i will have encoded, but this doesn't work as the decode function stops the program. Have I made an error in the coding? Thanks for all the help
Regards
def decodeMessage(ciphertext,keycode):
ciphertext =""
It appears that you are resetting ciphertext to a null string. as a result, your len(ciphertext) is 0 which means you ae not doing anything.
python 2.75
sig = 'abcd'
def test(sig):
sig = ""
print 'sig = ', sig
>>> test(sig)
sig = ''
>>> print sig
'abcd'
I am finding two problems with your decode message function:
def decodeMessage(ciphertext,keycode):
ciphertext =""
alphabet= "ABCDEFGHIJKLMNOPQRTUVWXYZ"
for i in range (len(ciphertext)):
character = ciphertext[i]
charCode = alphabet.find(character)
keycodeChar =keycode[i]
keyLetter = alphabet.find(keycodeChar)
position = (charCode - keyLetter)%25
cipherLetter = alphabet[position]
ciphertext =ciphertext - cipherLetter
return message
The first issue that I found was the fact that you pass in ciphertext to decodeMessage as a mandatory parameter and then you change the value of ciphertext to "" (an empty string). I would recommend changing the ciphertext in the parameters to something like "ct" to prevent that overlap.
The second issue I found was the fact you return message, but you don't perform any action on message. When running this program, you'll get a global error because message is not global yet you're calling message in the local scope without having defined it locally.
Now, onto another matter: Your encode method doesn't encode anything correctly. Look at the following output:
Press 1 to encode, 2 to decode, 9 to exit 1
What is the message some
What is the key? 18
YNLD
Press 1 to encode, 2 to decode, 9 to exit 1
What is the message some
What is the key? 5
YNLD
Press 1 to encode, 2 to decode, 9 to exit 1
What is the message some
What is the key? 1
YNLD
All 'some's get encoded to 'YNLD' regardless of the key. To cipher something using a Caesar Cypher, you're going to want to use ords and chrs. Ord makes the character numerical, Chr makes the number into a letter. Consider the following function made in Python 3, for example:
from string import ascii_letters
def cypher_letter(letter, key):
if letter not in ascii_letters: #commas, question marks, etc
return letter
if letter.islower(): #lowercase and uppercase have differing ord values
lower, upper = ord('a'), ord('z') # values: 97 to 122
elif letter.isupper():
lower, upper = ord('A'), ord('Z') # values: 65 to 90
else:
print("Something went wrong.") #probably didn't enter valid letters
cypher = ord(letter) + key #if key is "1" and letter is 'a', 97 + 1
if cypher < lower: cypher += 26 #26 letters in alphabet, this is for looping
if cypher > upper: cypher -= 26 #back around if it exceeds upper,lower limits
return chr(cypher) #chr(98) = 'b'
The following code:
cyphered_words = []
keys = [18, 5, 1]
for key in keys:
encoded = ""
for letter in 'some':
encoded += (cypher_letter(letter, key)) #to cypher we pass the key
print(encoded)
cyphered_word.append(encoded)
Outputs this:
Kgewlzafy hjwllq dgfy, oalz ugehdwp dwllwjk!
Xtrjymnsl uwjyyd qtsl, bnym htruqjc qjyyjwx!
Tpnfuijoh qsfuuz mpoh, xjui dpnqmfy mfuufst!
Cyphering and decyphering is almost the same thing. It's like they're yin and yang or something, so the decypher function would look like:
def decrypt_message(message, key):
decyphered_text = ""
for letter in message:
decyphered_text += cypher_letter(letter, (key*-1)) #to decypher we pass the negative key
return decyphered_text
And a loop to decrypt our 3 'some's:
for count, word in enumerate(cyphered_words):
print(decrypt_message_k(word, keys[count]))
And the output:
Something pretty long, with complex letters!
Something pretty long, with complex letters!
Something pretty long, with complex letters!
I hope this helps you get on the right track.