Friday, January 8, 2016

I am trying to teach myself to program using the interactivepython.org website. I have run into a problem that seems to be way over my head. I've been working on it for 3 hours straight and am racking my noggin. Not sure how to break this down at all.
Problem:
Decoding a secret message:
The description may seem daunting, but the solution is not that hard. You can use the built-in string datatype with the associated built-in functions and while loop (with ‘len’ function) or a for loop (with ‘in’ operator) to traverse the string. Also, use the ’chr’ and ’ord’ functions (which are based on ASCII code) discussed in course material. Make sure to look at the examples in the course material and do #18 and #19 in Exercises 2. Answer for #19 is provided and it can give valuable hints for solving this problem.

Your country is at war and your enemies are using a secret code to communicate with each other. You have managed to intercept a message that read as follows:
:mmZ\dxZmx]Zpgy
The message is obviously encrypted using the enemy’s secret code. You have just learned that their encryption method is based upon the ASCII code (you can find this set easily by searching online). Individual characters in a string are encoded using this system. For example, the letter ‘A’ is encoded using the number 65 and ‘B’ is encoded using the number 66.
Your enemy’s secret code takes each letter of the message and encrypts it as follows (using a secret key):
If (OriginalChar + Key > 126) then
    EncryptedChar = ((OriginalChar + Key) - 127) + 32
Else 
    EncryptedChar = (OriginalChar + Key)
For example, if the enemy uses Key = 10 then the message ”Hey” would be encrypted as:
Character   ASCII
H         72
e         101
y         121

Encrypted H = (72 + 10) = 82 = R in ASCII
Encrypted e = (101 + 10) = 111 = o in ASCII
Encrypted y = 32 + ((121 + 10) - 127) = 36 = $ in ASCII
Consequently, “Hey” would be transmitted as “Ro$”.
Write a program that decrypts the intercepted message. You only know that the key used is a number between 1 and 100. Your program should try to decode the message using all possible keys between 1 and 100. When you try the valid key, the message will make sense. For all other keys, the message will appear as gibberish.
HINT: You will need to implement a decrypt function that takes in an encrypted message as string and a key as integer and returns the decrypted message as string. You can decrypt each letter of the message as follows:
If (EncryptedChar - Key < 32) then
    DecryptedChar = ((EncryptedChar - Key) + 127) - 32
Else
    DecryptedChar = (EncryptedChar - Key)
NOTE: You should also implement an encrypt function that takes in a regular message as string and a key as integer and returns the corresponding encrypted message as string (the algorithm to encrypt a message is mentioned above in the problem description). This function would help you in encrypting any regular message, which then can be passed to your decrypt function to be decrypted.

For Encryption: You should ask the user for any regular message and a key and output the corresponding encrypted message.
Sample run:
Enter a regular message to encode:
Attack at dawn!
Enter a key value (between 0 and 100) for encoding:
88
The encoded message is: 
:mmZ\dxZmx]Zpgy

For Decryption: You should ask the user for an encrypted message and output 100 well-formatted, decrypted messages (using keys between 1 and 100) along with the corresponding key value.
Sample run (the gibberish messages below are not accurate):
Enter an encrypted message to decode:
:mmZ\dxZmx]Zpgy 
The following are the decoded messages for keys 1 to 100:
Key: 1 –> Decoded Message: whfuihwuiidh89
Key: 2 –> Decoded Message: 9ehkaOY3ewine
...
Key: 87 –> Decoded Message: Buubdl!bu!ebxo
Key: 88 –> Decoded Message: Attack at dawn!
...
Key: 100 –> Decoded Message: on3dwp389/wi8
This is the code I currently have:
def encrypt(message, key):
    result = ""
    for char in message:
        result += encryptedChar
    return result
shareimprove this question
  
The description of your problem seems daunting, but the solution is not that hard. You can use the built-instring datatype with the associated built-in functions and while loop (with 'len' function) or a forloop (with 'in' operator) to traverse the string. Also, use the 'chr' and 'ord' functions (which are based on ASCII code). – Brian Cain Nov 14 '13 at 17:43
  
You should try & use string.make_trans('plaintext', 'ciphertex') in the string library. – Ashish Nitin Patil Nov 14 '13 at 17:44
  
Yah i've read that about 500 times. Thanks! – TYPKRFT Nov 14 '13 at 17:45
  
the code you have probably raises an error? since you have no encryptedChar? it tells you exactly how to get the encrypted char ... – Joran Beasley Nov 14 '13 at 17:52 
  
Thanks Joran I have had no issues with most of the problems until now. I still dont understand how to do this, though. – TYPKRFT Nov 14 '13 at 17:54

2 Answers


Here is a simpler (but longer) answer as Joran Beasley's.
After you understand, that you can get the 'number' of a character with ord() and 'recover' the character with chr() it is quiet simple to 'translate' the code you got into correct python code.
Beginning with the following part:
If (OriginalChar + Key > 126) then
    EncryptedChar = ((OriginalChar + Key) - 127) + 32
Else 
    EncryptedChar = (OriginalChar + Key)
If you start out with the code you already wrote you can translate the above into:
def encrypt(message, key):
    result = ""
    for char in message:
        if (ord(char) + key > 126):
            result += chr(ord(char) + key - 127 + 32)
        else:
            result += chr(ord(char) + key)
    return result
You can do the same with the decryption part and write then a simple menu.
Here is the remaining code (you have to add the encrypt function at the top:
def decrypt(message):
    for key in range(1, 101):
        result = ""
        for char in message:
            if (ord(char) - key < 32):
                result += chr(ord(char) - key + 127 - 32)
            else:
                result += chr(ord(char) - key)
        print('key: {} -'.format(key), result)

if __name__ == '__main__':
    print('1 - Encrypt')
    print('2 - Decrypt')
    inp = input('select 1 or 2: ')
    if inp == '1':
        msg = input('Enter message: ')
        key = int(input('Enter key (1-100): '))
        print('Encrypted message:')
        print(encrypt(msg, key))
    else:
        msg = input('Enter message: ')
        decrypt(msg)
shareimprove this answer
  
I was trying to get him here :P (+1 all the same) – Joran Beasley Nov 14 '13 at 18:24 
  
I am going to try and comment every line of this.. could I private message either of you, maybe tom with the comment and maybe you can assess if I have grasped what I need to. I dont want to move on until I understand this like the back of my hand. – TYPKRFT Nov 14 '13 at 18:40 
1
I have created a so chatroom. You can post your questions/comments/... there. Now you, Joran Beasley, and I have write access, but everyone can see it. – TobiMarg Nov 14 '13 at 20:15
  
Thanks that is really too nice of you! – TYPKRFT Nov 15 '13 at 3:06

heres a fun solution
import string,codecs
class RotEncoder:
    def __init__(self,rot):
        self._rot = rot
    def _encChar(self,ch):
        return chr((ord(ch) + self._rot) if ord(ch) + self.rot =< 126 else  (((ord(ch) + self._rot) - 127) + 32))
    def _decChar(self,ch):
        return chr((ord(ch) - self._rot) if ord(ch) - self._rot >= 32 else (((ord(ch) - self._rot) + 127) - 32))
    def encode(self,txt,errors=[]):
        return "".join(map(self._encChar,txt)),1
    def decode(self,txt,errors=[]):
        return "".join(map(self._decChar,txt)),1
import re
def find_rot(search):
    t = re.match("rot\s?([0-9]+)",search.lower())
    if t.groups():
        val = int(t.groups()[0])
        return codecs.CodecInfo(
            name='rotcipher',
            encode=RotEncoder(val).encode,
            decode=RotEncoder(val).decode
            )

codecs.register(find_rot)

print ":mmZ\dxZmx]Zpgy".decode('rot88')
shareimprove this answer
  
Sorry that is way way above my head. I appreciate your input though. – TYPKRFT Nov 14 '13 at 18:03
  
ok what part of the original assignment do you not understand? maybe that would be a better question ... because from where I sit it looks like you posted your assignment and just wanted an answer ... so why do you think your existing solution does not work? – Joran Beasley Nov 14 '13 at 18:10
  
Well I am new and I dont understand how to break it down. I feel like I got through the lessons fine...then bam no clue. I know that I need two functions one for the encrypt and one for the decrypt. I know the encrypt needs to take in a message and a key 1-100 i think. I think that I need to grab the ascii value for each character but Im stuck after that. – TYPKRFT Nov 14 '13 at 18:16
  
so do you know how to get the ascii value for a character? if so why is that not part of your "attempt" above?– Joran Beasley Nov 14 '13 at 18:17
  
An answer would be helpful. I have answered most of my own questions on here but am just baffled by this. The instructions are becoming lost in translation to me and I don't know anyone else that knows this kind of stuff..That is why I am on here. I fear that I have gotten to a stuck point and will not understand python past this. – TYPKRFT Nov 14 '13 at 18:19
  
I know what needs to be done I think but I dont know how to write it. I know that I need to do ord() for each character right? – TYPKRFT Nov 14 '13 at 18:20
1
ok thats a good start ... so you have originalChar as char in your attempt above... what do you need to do to get encryptedChar? as far as an answer... if thats all you want I gave it above ... if you want to understand both the problem and the solution I will do my best to walk you to that... once you understand what you need to do here you can apply it to many other problems – Joran Beasley Nov 14 '13 at 18:21 
1
This answer is short, very nice and useful if one has a bit more experience with python, but hard to understand for a beginner. So I added a simpler answer (but not with such an elegant code). – TobiMarg Nov 14 '13 at 18:26
  
Joran I am still lost I appreciate your trying to hold my hand through this. I fear that maybe going back to school for something other than computer science will be in my future. Do you have any recommendations on maybe something I have missed in my studies and should have a better understanding of? – TYPKRFTNov 14 '13 at 18:31
1
it just takes practice ... and being able to recognize the class of problem and know what potential solutions are to that class of problem ... there is no innate programmer gene ... you just need to work at it (I posted this answer specifically because I knew it would make no sense to a beginner and I wanted you to make the logic leap on your own(with some help), believe me it happens you will be totally lost and all of a sudden some small thing will click and you will fully understand both the problem and the solution) ... 

http://stackoverflow.com/questions/19984548/how-can-i-tackle-this-cryptography

Cielo e terra (duet with Dante Thomas)