tags:

views:

790

answers:

5

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),
+1  A: 

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.

Mark Ransom
How would I build them into a single string?
Josh
@Josh: In Python, you can build a new string similar to using formatting characters in prints, e.g.: new_str = "String part: %s, Int part: %d" % (some_string, some_int)If you need to put it in a loop, first initialize the string to '' and then use += to add to it within the loop.
PTBNL
A: 

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.

Lennart Regebro
Okay, thank you. Just realized I posted the version with all of my syntax errors. I had one that was cleaned up, but thank you for the help
Josh
By the way, what are you meaning by "Please enter the shift:"
Josh
Your code does not handle punctuation. The original code ignored punctuation, as it is neither uppercase nor lowercase. In your example, you add k regardless.
Jeff B
@Josh: Ceasar Cipher does the cipher by shifting letters a certiain number. That's what I mean.
Lennart Regebro
@Jeff: Correctly, I don't handle punctuation, neither did Josh's original code. That's undefined in a typical ceasar cipher anyway. The original code does did differ between uppercase and lowercase, and did add k regardless. I do the same.
Lennart Regebro
Actually, the original code only adds k if letter.islower() or letter.issupper(), and punctuation is neither. Also, despite punctuation being undefined, it is probably best to either leave it alone or correctly shift it, otherwise you message could become undecipherable in the case that punctuation IS used.
Jeff B
Ah, I see what you mean. If you have plaintext punctuation, especially if that includes spaces, cracking it becomes so much easier. So in fact you shouldn't really leave it alone, you should raise an error if there is any. As an old cryptologist I just took that for granted. :-)
Lennart Regebro
+1  A: 

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
Jeff B
+1  A: 

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.

kaizer.se
This question is just begging for a sweet application of string translate. Well done :)
Eric Wendelin
A: 

Is there any good sites or books that I can use for beginners on python?

Josh