Reputation:
I'm trying to make a "Caesar's Cipher" while using python..this is what I have so far. Could anyone tell me how this is looking? Am I going in the right direction? What am I missing? When I run the program to say for example (josh is cool) I don't get the cipher on the same line. It looks like this when I do main(3)
m
r
v
k
l
v
f
r
r
o
But it puts each letter on a new line. How could I do it so that it is on one line?
def main(k):
if k<0 or k>231:
print "complaint"
raise SystemExit
Input = raw_input("Please enter Plaintext to Cipher")
for x in range(len(Input)):
letter=Input[x]
if letter.islower():
x=ord(letter)
x=x+k
if x>122:
x=x-122+97
print chr(x),
if letter.isupper():
x=ord(letter)
x=x+k
if x>90:
x=x-90+65
print chr(x),
Upvotes: 2
Views: 15045
Reputation: 5341
I like kaizer.se's answer, but I think I can simplify it using the string.maketrans function:
import string
first = raw_input("Please enter Plaintext to Cipher: ")
k = int(raw_input("Please enter the shift: "))
shifted_lowercase = ascii_lowercase[k:] + ascii_lowercase[:k]
translation_table = maketrans(ascii_lowercase, shifted_lowercase)
print first.translate(translation_table)
Upvotes: 6
Reputation: 509
Here is a oneliner.
>>> brutus=lambda message,cipher,direction:''.join([chr((ord(letter)+(cipher*direction))%256) for letter in message])
>>> encrypted= brutus('Message to be encrypted',14,1) #direction=1 for encryption
>>> encrypted
'[s\x81\x81ous.\x82}.ps.s|q\x80\x87~\x82sr'
>>> brutus(encrypted,14,-1) # direction=-1 for decryption
'Message to be encrypted'
>>>
Upvotes: 0
Reputation: 1
For Python 3.3, try using the ord(), chr() and .isalpha functions:
m = input("What is your message?: ")
s = int(input("What is the shift?: "))
for i in m:
if i.isalpha():
if (ord(i)+s)>90:
print(chr(ord(i)+s-26),end=""),
elif chr(ord(i)+s-26)<65:
print("The shift is invalid")
else:
print(chr(ord(i)+s),end=""),
else:
pass
Upvotes: 0
Reputation: 9709
I very simple, 3-shift solution without Umlauts and alike would be:
def caesar(inputstring):
shifted=string.lowercase[3:]+string.lowercase[:3]
return "".join(shifted[string.lowercase.index(letter)] for letter in inputstring)
and reverse:
def brutus(inputstring):
shifted=string.lowercase[-3:]+string.lowercase[:-3]
return "".join(shifted[string.lowercase.index(letter)] for letter in inputstring)
using it:
caesar("xerxes")
Upvotes: 0
Reputation: 172219
Barring the syntax errors, your code seems to work.
However, I took the liberty of removing all duplicates, and cleaning it up:
first = raw_input("Please enter Plaintext to Cipher: ")
k = int(raw_input("Please enter the shift: "))
result = ''
for second in first:
x=ord(second)
x=x+k
if x>90 and x<122:
x=x-26
elif x>122:
x=x-26
result += chr(x)
print first
print result
Also "first" and "second" are really bad names for those variables. "Input" and "letter" is probably better.
Upvotes: 0
Reputation: 49803
Here is a different method to show how we can handle this in a very clean way. We define an input alphabet and an output alphabet, then a translation table and use unicode.translate()
to do the actual encryption.
import string
# Blatantly steal Lennart's UI design
first = unicode(raw_input("Please enter Plaintext to Cipher: "), "UTF-8")
k = int(raw_input("Please enter the shift: "))
in_alphabet = unicode(string.ascii_lowercase)
out_alphabet = in_alphabet[k:] + in_alphabet[:k]
translation_table = dict((ord(ic), oc) for ic, oc in zip(in_alphabet, out_alphabet))
print first.translate(translation_table)
It can be extended to uppercase letters as needed.
Upvotes: 1
Reputation: 30099
This code should work pretty well. It also handles arbitrary offsets, including negative.
phrase = raw_input("Please enter plaintext to Cipher: ")
shift = int(raw_input("Please enter shift: "))
result = ''
for char in phrase:
x = ord(char)
if char.isalpha():
x = x + shift
offset = 65
if char.islower():
offset = 97
while x < offset:
x += 26
while x > offset+25:
x -= 26
result += chr(x)
print result
The other way to do it, with a slightly different cipher, is simply rotate through all characters, upper and lower, or even all ascii > 0x20.
phrase = raw_input("Please enter plaintext to Cipher: ")
shift = int(raw_input("Please enter shift: "))
result = ''
for char in phrase:
x = ord(char)
x = x + shift
while x < 32:
x += 96
while x > 127:
x -= 96
result += chr(x)
print result
Upvotes: 2
Reputation: 308121
Put a comma after each print statement; it will still put a space between the characters, but they'll all be on the same line. If you need to print them without the spaces, build them all into a single string and print that at the end.
Upvotes: 1