如何在Python(2.7)中制作Caesar解码器循环?

时间:2014-02-19 03:07:52

标签: python list python-2.7 encryption decoder

经过多次挫折之后,我制作了我的第一个凯撒解码器:)

但现在的问题是让程序循环......

例如,如果我们想要转移 doge 1,没问题,那就是ephf ......

但是xyz怎么样,转变是4 ???

所以编程专业人员帮助第一次新手,也就是新手:P 感谢...

import string
def main():        
    inString = raw_input("Please enter the word to be "
                         "translated: ")
    key = int(raw_input("What is the key value? "))

    toConv = [ord(i) for i in inString] #now want to shift it by key
    toConv = [x+key for x in toConv]
    #^can use map(lambda x:x+key, toConv)
    result = ''.join(chr(i) for i in toConv)

    print "This is the final result due to the shift", result

5 个答案:

答案 0 :(得分:0)

只需将key添加到所有实际字符代码中,然后如果添加的值大于z,则使用字符代码z取模,并将其添加为字符代码a

inString, key = "xyz", 4
toConv = [(ord(i) + key) for i in inString] #now want to shift it by key
toConv = [(x % ord("z")) + ord("a") if x > ord("z") else x for x in toConv]
result = ''.join(chr(i) for i in toConv)
print result   # cde

答案 1 :(得分:0)

一般来说,要做一些“换行”,你可以使用模数函数(Python中的%)和你想要包装的数字,以及你希望它包装的范围。例如,如果我想要的话将数字1到10打印出数百万次,我会这样做:

i = 0
while 1:
    print(i%10+1)
    # I want to see 1-10, and i=10 will give me 0 (10%10==0), so i%10+1!
    i += 1

在这种情况下,它有点困难,因为你使用ord,它没有一个很好的“范围”值。如果你做过类似string.ascii_lowercase的事情,你可以做......

import string
codex = string.ascii_lowercase

inString = "abcdxyz"
key = 3
outString = [codex[(codex.index(char)+key)%len(codex)] for char in inString]

但是,由于您使用ord,我们会从ord('A') == 65转到ord('z')==122,因此范围为0 - > 57(例如range(58),常数为65.换句话说:

codex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz"
# every char for chr(65) -> chr(122)

codex = ''.join([chr(i+65) for i in range(58)]) # this is the same thing!

我们可以这样做,但它将包含字符[\] ^ _`

inString, key = 'abcxyzABCXYZ', 4
toConv = [(ord(i)+key-65)%58 for i in inString]
result = ''.join(chr(i+65) for i in toConv)
print(result)
# "efgBCDEFG\\]^"

答案 2 :(得分:0)

我建议使用string.translate()

所以,我们可以做到以下几点:

key = 1
table = string.maketrans(string.ascii_lowercase + string.ascii_uppercase, string.ascii_lowercase[key:] + string.ascii_lowercase[:key] + string.ascii_uppercase[key:] + string.ascii_uppercase[:key])

然后我们可以按如下方式使用它:

'doge'.translate(table) # Outputs 'ephf'
'Doge'.translate(table) # Outputs 'Ephf'
'xyz'.translate(table)  # Outputs 'yza'

特别是,这不会更改不是ascii小写或大写字符的字符,例如数字或空格。

'3 2 1 a'.translate(table) # Outputs '3 2 1 b'

答案 3 :(得分:0)

这是我编写的易于理解的Python代码。另外,我认为经典的Caesar密码没有定义如何处理标点符号;我认为经典的秘密信息是不经验证的,只包含字母。我写这篇文章只是为了处理经典的罗马字母,并且不改变任何其他字符。

作为奖励,您可以使用此代码移位13来解码ROT13编码的笑话。

def caesar_ch(ch, shift):
    """
    Caesar cipher for one character.  Only shifts 'a' through 'z'
    and 'A' through 'Z'; leaves other chars unchanged.
    """
    n = ord(ch)
    if ord('a') <= n <= ord('z'):
        n = n - ord('a')
        n = (n + shift) % 26
        n = n + ord('a')
        return chr(n)
    elif ord('A') <= n <= ord('Z'):
        n = n - ord('A')
        n = (n + shift) % 26
        n = n + ord('A')
        return chr(n)
    else:
        return ch

def caesar(s, shift):
    """
    Caesar cipher for a string.  Only shifts 'a' through 'z'
    and 'A' through 'Z'; leaves other chars unchanged.
    """
    return ''.join(caesar_ch(ch, shift) for ch in s)

if __name__ == "__main__":
    assert caesar("doge", 1) == "ephf"

    assert caesar("xyz", 4) == "bcd"

    assert caesar("Veni, vidi, vici.", 13) == "Irav, ivqv, ivpv."

最后的部分是代码的“自检”。如果您将其作为独立程序运行,它将自行测试,并在测试失败时“断言”。

如果您对此代码有任何疑问,请询问,我会解释。

答案 4 :(得分:0)

我知道这是一个古老的话题,但我今天碰巧正在努力。我发现这个帖子的答案很有用,但他们似乎都在决定循环。我想方设法使用模数(余数)运算符(%)来实现相同的目标。这允许数字保持在表格的范围内并循环。它还允许轻松解码。

# advCeaser.py
# This program uses a ceaser cypher to encode and decode messages
import string

def main():
    # Create a table to reference all upper, lower case, numbers and common punctuation.
    table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890,.!?-@'

    print 'This program accepts a message and a key to encode the message.'
    print 'If the encoded message is entered with the negative value of the key'
    print 'The message will be decoded!'

    # Create accumulator to collect coded message 
code =''

    # Get input from user: Message and encode key
    message = raw_input('Enter the message you would like to have encoded:')
    key = input('Enter the encode or decode key: ')

    # Loop through each character in the message
    for ch in message:
        # Find the index of the char in the table add the key value
        # Then use the remainder function to stay within range of the table.
        index = ((table.find(ch)+key)%len(table))

        # Add a new character to the code using the index
        code = code + table[index]

    # Print out the final code
    print code

main()

编码和解码输出如下所示。

编码:

This program accepts a message and a key to encode the message.
If the encoded message is entered with the negative value of the key
The message will be decoded!
Enter the message you would like to have encoded:The zephyr blows from the east to the west!
Enter the encode or decode key: 10
croj0ozr92jlvy73jp2ywj4rojok34j4yj4roj7o34G

解码:

This program accepts a message and a key to encode the message.
If the encoded message is entered with the negative value of the key
The message will be decoded!
Enter the message you would like to have encoded:croj0ozr92jlvy73jp2ywj4rojok34j4yj4roj7o34G
Enter the encode or decode key: -10
The zephyr blows from the east to the west!

很抱歉,如果我的格式看起来像catywompus我昨天发现了stackoverflow!是的,我的字面意思是:)