user186509
user186509

Reputation:

Caesar's Cipher using python, could use a little help

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

Answers (8)

Neil Vass
Neil Vass

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

thekindlyone
thekindlyone

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

user2997187
user2997187

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

dorvak
dorvak

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

Lennart Regebro
Lennart Regebro

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

u0b34a0f6ae
u0b34a0f6ae

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

Jeff B
Jeff B

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

Mark Ransom
Mark Ransom

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

Related Questions