Caesar cipher in Python, exercise - python

I'm stuck in solving the following exercise:
"*From the standard input you will get an integer n and a message encrypted by Caesar cipher (i.e. shifted by n letters down the alphabet). Decrypt the message and print it.
Hint: Functions chr a ord, function print with parameter end=''.
Try Also:
-3#Jrf rf rnxz*"
**Sample Input:
5#Rfrf rjqj rfxt**
**Sample Output:
Mama mele maso**
The code I've wrote is the following:
posun, zprava = input().split("#")
for i in zprava:
a = ord(i) - int(posun)
print(chr(a), end='')
But except for having the requested output, the exercise is tagged as wrong. Any suggestion?

Related

Why does map function return None?

I'm trying to code another encrypter, I'm having problems with the decoding process.
I've read a lot of StackOverflow's questions about this argument, I alredy know that someone is going to mark this question as a duplicate but I'm writing this because I can't find a solution to my problem.
The encode function gives me this string
4697625275273471234347364527724769
That is the encoded message (it says 'Hello world!') and I have the 'Key' (randomly generated every time I start the program), that cointains the combiantions of numbers needed to decode the message.
Here is the key
12040512030417060213060413030716060915090216080313040713060215090916020217020419040215050918070812050414030615020715020512061602071404091407041805160407170516030919090718050315070618020719070218050812030317020918060815070817020816040318080414060914060414050419030818030513020419030517040912040218020918030616050313050413040319070618020617060518060314090616070612080615060613020912040413070619070918050217040512070813020816020513090812090218080715020317050217050313070419020717090712060814020816030518040317030616050915020215030516050518080314040619060815030816020613040518080817060913070312080316050717020714070212090915090812090517030916060218091905051608071904041303021209031606081707051209081908041302051808021602081202041508031708041204031608041504031708051307051908081405091809051207091408061805061806021306061902021805041706081902061303031606051803091309061202031504061702021206091402091604041906041709091609061506081908091707021604061604081309051508091905041903031903071202021705061409091205091803071409041505071204061709041909091209061409051309041707031207041709061704021804051907071703031707091605081907051506041308051305071407031708031607021902051802051705041209071909081709051804041804091403021503031507071208051307021507041806051404031904031903061208041607031204071609091904091809031807031206041308091907041908031809071704031807071909021209041509071304041804071309071707061603081305051606031304021208071908021407081803021807021406071808051602041502061903091205051508051206031803081802021503061602031403081403091909061409081703021606071504051609041409031504021308021509051905031206071605021206051507021408021402061907031502041705091504081308081207051902091704061603071503041202061605061303091507091408041906091608061609081504041706071205021405021603041303041305031607081403051703041406061304081306071308061307081602091207061203091403071503091202051607041308071506021407071803031305021309031805091203061906051406031304061704071207071706031508061206021709021404051403041508071704041203071403031306081705051709081708061706041207031909031309091507031708021404041704081702031404071307071203051409071
it's a bit long.
And now that I have the parameters you need to put them in the decoder
input_text = input('Encrypted MSG\n> ')
key = input('Key\n> ')
alphabet = list(" qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890èéòç#à°#ù§[]+*,;.:-_<>£$₽%&()=?ì^/|!ėëęēêĖËĘĒÉÈÊūûüúŪÛÜÚÙīïįíìîĪÏĮÍÌκōøõœöôóŌØÕŒÖÓÒãåāáâäæÃÅĀªÀÁÂÄÆßẞÇñÑ¥¢∆¶×÷π√•`~©®™✓йцукенгшщзхфывапролджэячсмитьбюЙЦУКЕНГШЩЗХФЫВАПРОЛДЖЭЯЧСМИТЬБЮ⌂☻‼‰╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤▬╥╙╘╒╓╫╪┘┌¤█▄▌▐▀αΣσ░▒▓│┤╡╢╖╕╣║╗╝¿þ¼½¾ⁿ⌠⌡≤≥±≡∩∞ΘΩð«»⌐¬¨↨↑↓→←↔₧☼♥♦♣♠♂♀♪◘○◙►◄▲▼Þ‘’“”„☭卐")
key = key.replace('0', '')
key = key.replace('1', ' ')
key = key.split()
key.insert(0,'1')
charmap = zip(key, alphabet)
_map = dict(charmap)
output_text = ''.join(str(_map.get(c)) for c in input_text)
print(f'Output\n> {output_text}')
The output [ACTUAL]
Encrypted MSG
> 4697625275273471234347364527724769
Key
> 12040512030417060213060413030716060915090216080313040713060215090916020217020419040215050918070812050414030615020715020512061602071404091407041805160407170516030919090718050315070618020719070218050812030317020918060815070817020816040318080414060914060414050419030818030513020419030517040912040218020918030616050313050413040319070618020617060518060314090616070612080615060613020912040413070619070918050217040512070813020816020513090812090218080715020317050217050313070419020717090712060814020816030518040317030616050915020215030516050518080314040619060815030816020613040518080817060913070312080316050717020714070212090915090812090517030916060218091905051608071904041303021209031606081707051209081908041302051808021602081202041508031708041204031608041504031708051307051908081405091809051207091408061805061806021306061902021805041706081902061303031606051803091309061202031504061702021206091402091604041906041709091609061506081908091707021604061604081309051508091905041903031903071202021705061409091205091803071409041505071204061709041909091209061409051309041707031207041709061704021804051907071703031707091605081907051506041308051305071407031708031607021902051802051705041209071909081709051804041804091403021503031507071208051307021507041806051404031904031903061208041607031204071609091904091809031807031206041308091907041908031809071704031807071909021209041509071304041804071309071707061603081305051606031304021208071908021407081803021807021406071808051602041502061903091205051508051206031803081802021503061602031403081403091909061409081703021606071504051609041409031504021308021509051905031206071605021206051507021408021402061907031502041705091504081308081207051902091704061603071503041202061605061303091507091408041906091608061609081504041706071205021405021603041303041305031607081403051703041406061304081306071308061307081602091207061203091403071503091202051607041308071506021407071803031305021309031805091203061906051406031304061704071207071706031508061206021709021404051403041508071704041203071403031306081705051709081708061706041207031909031309091507031708021404041704081702031404071307071203051409071
Output
> NoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNone NoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNone
The output [EXPECTED]
Encrypted MSG
> 4697625275273471234347364527724769
Key
> 12040512030417060213060413030716060915090216080313040713060215090916020217020419040215050918070812050414030615020715020512061602071404091407041805160407170516030919090718050315070618020719070218050812030317020918060815070817020816040318080414060914060414050419030818030513020419030517040912040218020918030616050313050413040319070618020617060518060314090616070612080615060613020912040413070619070918050217040512070813020816020513090812090218080715020317050217050313070419020717090712060814020816030518040317030616050915020215030516050518080314040619060815030816020613040518080817060913070312080316050717020714070212090915090812090517030916060218091905051608071904041303021209031606081707051209081908041302051808021602081202041508031708041204031608041504031708051307051908081405091809051207091408061805061806021306061902021805041706081902061303031606051803091309061202031504061702021206091402091604041906041709091609061506081908091707021604061604081309051508091905041903031903071202021705061409091205091803071409041505071204061709041909091209061409051309041707031207041709061704021804051907071703031707091605081907051506041308051305071407031708031607021902051802051705041209071909081709051804041804091403021503031507071208051307021507041806051404031904031903061208041607031204071609091904091809031807031206041308091907041908031809071704031807071909021209041509071304041804071309071707061603081305051606031304021208071908021407081803021807021406071808051602041502061903091205051508051206031803081802021503061602031403081403091909061409081703021606071504051609041409031504021308021509051905031206071605021206051507021408021402061907031502041705091504081308081207051902091704061603071503041202061605061303091507091408041906091608061609081504041706071205021405021603041303041305031607081403051703041406061304081306071308061307081602091207061203091403071503091202051607041308071506021407071803031305021309031805091203061906051406031304061704071207071706031508061206021709021404051403041508071704041203071403031306081705051709081708061706041207031909031309091507031708021404041704081702031404071307071203051409071
Output
> Hello world!
The debug that I made with Visual Studio Code show that the problem is the map function
Can you help me please?
Thanks
You read one by one digit on the Encrypted message.
So if you have a 4 on your encrypted message to find 4 on the map you need to have 141 on your key due to the processing you do on your key.
In your exemple you dont have 141 on your generated key thats why you get None.
I change the key to use
12141512030417060213060413030716060915090216080313040713060215090916020217020419040215050918070812050414030615020715020512061602071404091407041805160407170516030919090718050315070618020719070218050812030317020918060815070817020816040318080414060914060414050419030818030513020419030517040912040218020918030616050313050413040319070618020617060518060314090616070612080615060613020912040413070619070918050217040512070813020816020513090812090218080715020317050217050313070419020717090712060814020816030518040317030616050915020215030516050518080314040619060815030816020613040518080817060913070312080316050717020714070212090915090812090517030916060218091905051608071904041303021209031606081707051209081908041302051808021602081202041508031708041204031608041504031708051307051908081405091809051207091408061805061806021306061902021805041706081902061303031606051803091309061202031504061702021206091402091604041906041709091609061506081908091707021604061604081309051508091905041903031903071202021705061409091205091803071409041505071204061709041909091209061409051309041707031207041709061704021804051907071703031707091605081907051506041308051305071407031708031607021902051802051705041209071909081709051804041804091403021503031507071208051307021507041806051404031904031903061208041607031204071609091904091809031807031206041308091907041908031809071704031807071909021209041509071304041804071309071707061603081305051606031304021208071908021407081803021807021406071808051602041502061903091205051508051206031803081802021503061602031403081403091909061409081703021606071504051609041409031504021308021509051905031206071605021206051507021408021402061907031502041705091504081308081207051902091704061603071503041202061605061303091507091408041906091608061609081504041706071205021405021603041303041305031607081403051703041406061304081306071308061307081602091207061203091403071503091202051607041308071506021407071803031305021309031805091203061906051406031304061704071207071706031508061206021709021404051403041508071704041203071403031306081705051709081708061706041207031909031309091507031708021404041704081702031404071307071203051409071
It finds w for 4 which is the result intended.
Best regards

Python XOR Encryption program sometimes doesn't work

I am trying to make a simple xor encryption program in python and what I have now is working almost fine, only sometimes it doesn't and I just can't figure out why. For example, if I input 'hello' and the key '1234' it will encrypt it to YW_X^ and if I then decrypt this with the same key it will print 'hello'. But if I change the key to 'qwer' the encrypted message is something like '^Y^R ^^^^' and if I try to decrypt it, 'heERQWERoi' comes out.
This is the code:
from itertools import cycle, izip
choice = int(raw_input('Press 1 to encrypt, 2 to decrypt. '))
if choice == 1:
message = raw_input('Enter message to be encrypted: ')
privatekey = raw_input('Enter a private key: ')
encrypted_message = ''.join(chr(ord(c)^ord(k)) for c,k in izip(message, cycle(privatekey)))
print 'Encrypted message:'
print encrypted_message
elif choice == 2:
todecrypt = raw_input('Enter a message to be decrypted: ')
otherprivatekey = raw_input('Enter the private key: ')
decrypted_message = ''.join(chr(ord(c)^ord(k)) for c,k in izip(todecrypt, cycle(otherprivatekey)))
print 'Decrypted message:'
print decrypted_message
I have no idea what is wrong with it so I would really appreciate some help, thank you!
It's probably working fine, but you are getting characters which you may not be able to re-input into your terminal directly as they don't correspond to the ordinarily inputtable ASCII characters. In particular, with the key qwer, the values of ord become [25, 18, 9, 30, 30], which you may have a hard time inputting (cf. this table).
The similar problem will not occur if you use 1234 as a key as in that case the values are [89, 87, 95, 88, 94] which correspond to "normal" characters.
Your script is printing non-printing characters, which sometimes can't be copy/pasted. You could encode the ciphertext into a format that uses only the characters abcdef0123456789, which lets you display it without issue:
print encrypted_message.encode('hex')
You can then decode it when the user types it in once more:
todecrypt = raw_input('Enter a message to be decrypted: ').decode('hex')

How to 'encrypt' a file

Just trimmed this down big time
I have an overall assignment that must read a file, encrypt it and then write the encrypted data to a new file.
what i've tried is this:
filename=input("Enter file name:")
fr=open(filename)
keep_going=0
data = fr.readline()
fw=open('encrypted_file.txt', 'w')
for x in range(len(data)):
fw.write(data[x])
fw.close()
fr.close()
If your goal is just to exchange the letters in a string with others that you specify, then the solution is the following:
decrypted = 'abcdefghijklmnopqrstuvwxyz' #normal alphabet
encrypted = 'MNBVCXZLKJHGFDSAPOIUYTREWQ' #your "crypted" alphabet
#Encription
text = 'cryptme' #the string to be crypted
encrypted_text = ''
for letter in text:
encrypted_text += encrypted[decrypted.find(letter)]
print encrypted_text
#will print BOWAUFC
#Decription
text = encrypted_text #"BOWAUFC" in this example
decrypted_text = ''
for letter in text:
decrypted_text += decrypted[encrypted.find(letter)]
print decrypted_text
#will print cryptme
Note that your "crypted alphabet" do not convert any white space or any symbols but the lowercase letters, if you have other symbols in your text you have to include them as well.
However, this is not the proper way to encrypt anything! As suggested by others already, look up for a proper encryption algorithm.
I would suggest you look into Simple Crypt, this all depends on the level of security you want.
If I understand your question enough, Simple Crypt should do the job that you need.
https://pypi.python.org/pypi/simple-crypt
Here's a very simple implementation of the Vigenère Cipher I made:
from string import ascii_uppercase as alphabet
val = {}
for x in xrange(len(alphabet)):
val[alphabet[x]] = x
val[x] = alphabet[x]
encrypt = lambda a, b: ''.join(val[(val[a[i]]+val[b[i%len(b)]])%26] for i in xrange(len(a)))
decrypt = lambda a, b: ''.join(val[(val[a[i]]-val[b[i%len(b)]])%26] for i in xrange(len(a)))
Where a is the message and b is the key (I know it's written a bit tersely, but it was for a code golf competition). There are plenty of ciphers out there; you don't have to use this one, and probably shouldn't. It is just meant to get you thinking about possible ways to go about doing this. A very simple cipher that I think is good for your purposes is the Caesar Cipher.
One other thing that I'd like to point out is that your code doesn't look to modular -- one of your teacher's requirements -- right now. I'd recommend breaking it down to a function to open a file, a function to perform the actual **cryption, and a "main" function to take the user's input and call the other functions.
Best of luck to you!

How to decrypt a vigenere columnar transposition cipher

I am going through old exams, my final is in a few days. I want to decrypt a ciphertext, it was first encrypted by vigenere and then encrypted by columna transposition. How do I decrypt to get original message?
message -> rgyqhbmnwaazxcajittuzqyagkx
vigenere key -> final
columnar transposition key -> exam
I have spent hours on this, but am not getting anything out. I first want to decrypt by columnar then Vigenere. I think output should look English, but am just getting junk. My vigenere code is below, I guess the problem is with the columnar, all the codes I have come across take numbers as key, but I have a letter key.
def decrypt(message, password):
decrypted = ''
for i in range(0, len(message)):
letter = ord(message[i]) - ord(password[i%len(password)]) + 65
if letter < 65:
letter += 26
decrypted += chr(letter)
return decrypted
thanks
The columnar transposition does take a word as key, not a number. If "exam" is the key, then you write out the message from left to write in rows of four and read off the cipher text from top to bottom starting with column 3, then column 1, then column 4 then column 2. The order comes form the alphabetical order of the letters "e","x","a","m": "2nd", "4th", "1st", "3rd".
For example, to encrypt "THIS IS THE MESSAGE":
E X A M
----------
T H I S
I S T H
E M E S
S A G E
--> ITEG TIES SHSE HSMA
I.e., "ITEGTIESSHSEHSMA".
To decrypt do the reverse. I don't want to solve your homework for you, but I will say that, when you properly decrypt via the columnar transposition with "exam" you will find a string starting with "nzrawq..."
When you then further decrypt that string with the vigenere cipher you will indeed find English words, in particular a string starting with "ireallywant..."

Caesar Cipher (different to others)

Hey guys so I 'm trying to make a cipher following these sets of instructions:
Print a header.
Prompt the user to enter the name of the file with the encrypted message, the decode
key (the shift number), and the name of the file to store the decrypted message.
Read the encrypted message from the file.
Use the decode key to shift each character in the encrypted message by the
appropriate number to generate the new string corresponding to the decrypted message.
Save the decrypted message in the second file.
Print the encypted and decrypted messages on the screen.
I'm not allowed to use the ord() or chr() functions.
What really confuses me is the encrypted and decrypted files part. I don't really know how to code for this.
I'm pretty new to this so any help would be greatly appreciated.
Thanks in advance.
Note: It sounds like you're probably doing this as a school assignment. I highly recommend that you use the code below only as an example and not as a full solution. I would hate for there to be plagiarism issues surrounding your assignment and I'm sure your professor/teacher is knowledgeable at Googling for prior work. Good luck on your assignment!
I wrote a quick example of how I might try and tackle your problem. The example has a few known issues:
It doesn't deal with capital letters. (Other than to convert them to their lowercase counterparts.)
It doesn't deal with punctuation or non alphanumeric characters. (Numbers, spaces or line endings.)
There is no error checking.
If you try to convert a number < -25 it will throw up on you.
Probably the biggest problem that needed to be solved was the limitation of not using ord() and chr(). I bypassed that limitation by creating my own conversion list of letters to numbers and vice versa. A tricky corner case to make sure you deal with is what happens if the shift moves a letter outside of the conversion range [0,25].
As a side note if you want to decrypt a file you can simply open it up as the plaintext and use a negative offset whose absolute value is equal to the encrypting offset. Or in plain English, if you use the parameters:
infile = clear.txt, offset = 1, outfile = encrypted.txt
To decrypt you can use:
infile = encrypted.txt, offset = -1, outfile = decrypted.txt
caesarcipher.py
import itertools
letters = ['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']
numbers = range(26) # Numbers 0 - 25
lettersToNumbers = dict(zip(letters, numbers))
numbersToLetters = dict(zip(numbers, letters))
def printHeader():
""" Print the program informational header """
print """=======================================
Welcome to CaesarCipher - The unbreakable
Roman cipher.
======================================="""
def convertToNumber(letter):
""" Convert a letter to a number using our predefined conversion table
#param letter: The letter to convert to an integer value
#type letter: str
#rtype: int
"""
return lettersToNumbers[letter]
def convertToLetter(number):
""" Convert a number to a letter using our predefined conversion table
#param number: The number to convert to a letter
#type number: int
#rtype: str
"""
# If we shift outside of our range make sure to wrap
if number > 25:
return numbersToLetters[number%25]
elif number < 0:
return numbersToLetters[number+25]
else:
return numbersToLetters[number]
def shiftUp(letter, shift):
""" Shift letter up a given number of positions
#param letter: The letter we're shifting
#param shift: The number of positions to shift up
#type letter: str
#type shift: int
#note: For simplicity we encode both capital and lowercase letters
to the same values
"""
number = convertToNumber(letter.lower())
number += shift
return convertToLetter(number)
def prompt():
""" Prompt for user input
#rtype: tuple of str, int, str
"""
infile = raw_input("File to encrypt: ")
offset = int(raw_input("Encoding number: "))
outfile = raw_input("Encrypted file destination: ")
return (infile, offset, outfile)
def encrypt(infile, offset, outfile):
""" Encrypt the file using the given offset """
print "=== Plaintext input ==="
printFile(infile)
with open(infile) as red_file:
with open(outfile, 'w') as black_file:
for line in red_file:
for letter in line:
# Only convert alphabetic characters
if letter.isalpha():
black_file.write(shiftUp(letter, offset))
else:
black_file.write(letter)
print "=== Ciphertext output ==="
printFile(outfile)
def printFile(path):
""" Print the data in the given file """
with open(path) as print_file:
for line in print_file:
print line
printHeader()
encrypt(*prompt()) # `*` unpacks the tuple returned by `prompt()` into
# three separate arguments.
test.txt
abcdef
ABCDEF
This is some text I want to try and encrypt.
Example run:
mike#test:~$ python caesarcipher.py
=======================================
Welcome to CaesarCipher - The unbreakable
Roman cipher.
=======================================
File to encrypt: test.txt
Encoding number: 1
Encrypted file destination: test.out
=== Plaintext input ===
abcdef
ABCDEF
This is some text I want to try and encrypt.
=== Ciphertext output ===
bcdefg
bcdefg
uijt jt tpnf ufyu j xbou up usz boe fodszqu.
Since you say the file bits is your biggest problem, I assume function like:
def decaesar(message, shift):
pass
that does the decyphering for you on a string basis - that is, it takes the encrypted message as a string and gives you back the decrypted message as a string. If you haven't written that already, do that first, and test it with hard-coded strings. Ignore the "encrypted and decrypted files" bit at this stage - programming is all about solving one problem at a time.
Once you have that function and you're happy that it works, extending your program to deal with files instead of strings is as simple as asking:
Can I get a string with the contents of a file, given the file's name? , and conversely,
Can I write a string into a file with a given name?
If you can answer both of those with 'yes', then you can extend your program in this way without changing your decaesar function - your logic looks like this:
# Print header
encrypted_filename, decrypted_filename, shift = # get from user input
encrypted_message = # get the contents of encrypted_filename as a string
decrypted_message = decaesar(encrypted_message, shift)
# write decrypted_message to decrypted_filename
# print encrypted_message and decrypted_message
Usefully, Python's file IO works on exactly this principle of converting between strings and files. If you have a file open for reading:
in_file = open(filename)
, then the return value of:
in_file.read()
is exactly the string to answer the first point. Likewise, if you have a file open for writing:
out_file = open(filename, 'w')
. then:
out_file.write(my_string)
will put my_string into that file.
So that means that if you do already have your decaeser function, then you can slip this code into the pseudocode above at the appropriate places, and you will have a mostly working solution.

Categories