2

I am new to Python and decided to make my own Caesar cipher encryptor. I've made the encrypter and it is ok, however, the decrypter can only successfully decrypt one word. If I enter a sentence, it merges the decryption all together. Is there an easy fix for this?

def decrypt():
    ciphertext = raw_input('Please enter your Encrypted sentence here:')
    shift = input('Please enter its shift value: ')
    space = []

    cipher_ords = [ord(x) for x in ciphertext]
    plaintext_ords = [o - shift for o in cipher_ords]
    plaintext_chars = [chr(i) for i in plaintext_ords]
    plaintext = ''.join(plaintext_chars)
    print 'Decryption Successful'
    print "" 
    print 'Your encrypted sentence is:', plaintext

decrypt()
6
  • 1
    Are you sure the problem does not start with your encryptor? Commented Oct 24, 2016 at 18:19
  • Your code looks ok here. Can you provide is with input and expected output? Commented Oct 24, 2016 at 18:20
  • Also you should never use input as that allows for arbitrary code execution. Instead do int(raw_input()). Commented Oct 24, 2016 at 18:21
  • no because it is a seperate file. I simply imput 'lipps xlivi' with a shift of '4' which should translate to 'hello there'. However, I get 'hellothere' with my current code. Commented Oct 24, 2016 at 18:21
  • 2
    @MatthewWillis Your encrypted text does not have the "space" character shifted. Either shift that as well as part of your encyrption, or have your decrypter not try to "un-shift" the space Commented Oct 24, 2016 at 18:26

3 Answers 3

1

What I propose is to split your raw_input() at every space, iterate over each word in the split input, and then join the sentence back together with spaces. It seems to be the most canonical solution I could think of:

def decrypt():
    ciphertext = raw_input('Please enter your Encrypted sentence here:')
    shift = int(raw_input('Please enter its shift value: '))
    space = []

    # creat a list of encrypted words.
    ciphertext = ciphertext.split()

    # creat a list to hold decrypted words.
    sentence = []

    for word in ciphertext:
        cipher_ords = [ord(x) for x in word]
        plaintext_ords = [o - shift for o in cipher_ords]
        plaintext_chars = [chr(i) for i in plaintext_ords]
        plaintext = ''.join(plaintext_chars)
        sentence.append(plaintext)

    # join each word in the sentence list back together by a space.
    sentence = ' '.join(sentence)
    print 'Decryption Successful\n'
    print 'Your encrypted sentence is:', sentence

decrypt()

Output:

Please enter your Encrypted sentence here: lipps xlivi
Please enter its shift value:  4
Decryption Successful

Your encrypted sentence is: hello there

Notes:

  • Never just do input() in Python 2.x because it uses eval() implicitly - which can be very dangerous. Use int(raw_input()) instead.
  • I removed the extra print statement you had to create a new line. Append a new line to your second print statement instead.
Sign up to request clarification or add additional context in comments.

Comments

1

Based on your comment about "hello there" as input, I suspect that the issue has to do with unprintable ascii characters. You are missing two crucial parts of your Caesar cypher.

For the first issue, consider:

>>> chr(ord(' ') - 4)
'\x1c'

Oh no! 4 characters to the left of the space (32) is the...ASCII file separator! How did Caesar fit that on a clay tablet?

For the second issue:

>>> chr(ord('A') - 4)
'='

The 'A' should wrap around in a true Caesar cypher, but instead you are exploring the hinterlands (well, not really) of non-alphabetic ASCII codes.

You thus need to include two important steps:

  1. Exclude non-alphabetic characters from the Caesar cypher.
  2. Make sure that letters wrap when approach the end: A - 1 should equal Z.

1 Comment

so how do i do this?
1

Your probably wanted not to decrypt the space character as in your "encrypted" text it is not encrypted. If this is the case, here is the modified part of your code:

cipher_ords     = [ord(x)    if x != " " else -1  for x in ciphertext]
plaintext_ords  = [o - shift if o != -1  else -1  for o in cipher_ords]
plaintext_chars = [chr(i)    if i != -1  else " " for i in plaintext_ords]

(Let cipher_ords has -1 for each space symbol and consequenlty in plaintext_ords, too. In plaintext_chars this -1 will return back to the original space symbol.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.