1

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 –&gt; Decoded Message: whfuihwuiidh89
Key: 2 –&gt; Decoded Message: 9ehkaOY3ewine
...
Key: 87 –&gt; Decoded Message: Buubdl!bu!ebxo”
Key: 88 –&gt; Decoded Message: Attack at dawn!
...
Key: 100 –&gt; Decoded Message: on3dwp389/wi8

This is the code I currently have:

def encrypt(message, key):
    result = ""
    for char in message:
        result += encryptedChar
    return result
4

2 回答 2

2

这是 Joran Beasley 的一个更简单(但更长)的答案。

在你理解之后,你可以得到一个字符的“数字”ord()并用它“恢复”这个字符,chr()将你输入的代码“翻译”成正确的 python 代码非常简单。

从以下部分开始:

If (OriginalChar + Key > 126) then
    EncryptedChar = ((OriginalChar + Key) - 127) + 32
Else 
    EncryptedChar = (OriginalChar + Key)

如果您从已经编写的代码开始,您可以将上面的代码翻译成:

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

您可以对解密部分执行相同操作,然后编写一个简单的菜单。
这是剩余的代码(您必须encrypt在顶部添加函数:

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)
于 2013-11-14T18:20:31.440 回答
2

这是一个有趣的解决方案

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')
于 2013-11-14T18:01:27.833 回答