2

我只想打印字母,但它会打印 ASCII 的特殊字符。我的代码:

import string
def caesar(shift):
    alphabet = string.ascii_lowercase + string.ascii_uppercase
    dict={}
    emptylist=[]
    int(shift)
    for x in alphabet:
        emptylist.append(x)
        code = ""
        for letters in emptylist:
            code = chr(ord(letters) + shift)
            dict[letters]=code
    return dict
caesar(12)

我的输出:

'm': 'y', 'l': 'x', 'o': '{', 'n': 'z', 'q': '}', 'p': '|', 's ': '\x7f', 'r': '~', 'u': '\x81', 't': '\x80', 'w': '\x83', 'v': '\x82' , 'y': '\x85', 'x': '\x84', 'z': '\x86'

正确的输出:

'm':'y','l':'x','o':'a','n':'z','q':'c','p':'b','s ':'e','r':'d','u':'g','t':'f','w':'i','v':'h','y': 'k','x':'j','z':'l'

4

2 回答 2

5

使用ord()和更改字符代码不会将生成的字符限制在您的字典中。

我只是在你的字典中找到字母的索引,移动它,然后使用模运算符:

import string

def caesar(shift):
    alphabet = string.ascii_uppercase  # <- Change it back to what you had before
                                       #    and see what will happen.
    mapping = {}

    for letter in alphabet:
        index = alphabet.index(letter)
        mapping[letter] = alphabet[(index + shift) % len(alphabet)]

    return mapping

测试(字典不保留顺序,因此很难阅读):

>>> caesar(12)
{'A': 'M', 'C': 'O', 'B': 'N', 'E': 'Q', 'D': 'P', 'G': 'S', 'F': 'R', 'I': 'U', 'H': 'T', 'K': 'W', 'J': 'V', 'M': 'Y', 'L': 'X', 'O': 'A', 'N': 'Z', 'Q': 'C', 'P': 'B', 'S': 'E', 'R': 'D', 'U': 'G', 'T': 'F', 'W': 'I', 'V': 'H', 'Y': 'K', 'X': 'J', 'Z': 'L'}
于 2012-10-31T02:52:42.697 回答
5

让我们特别看一个错误:o: '{'.

注意ord('o')是 111,所以让我们看一下 中chr的整数range(111,130)

从 开始o,移动 12 位,将您带到{角色:

In [75]: ' '.join([chr(x) for x in range(111,130)])
Out[75]: 'o p q r s t u v w x y z { | } ~ \x7f \x80 \x81'
          ^ 1 2 3 4 5 6 7 8 9 ...12

所以你得到不正确输出的原因是因为你的公式

code = chr(ord(letters) + shift)

没有考虑到如果班次将您从与a-zor相关联的顺序中反弹出来会发生什么A-Z。(请注意, 和 的 ord 范围a-z也不A-Z连续!)


以下是有关如何修复的提示:

In [82]: alphabet = string.ascii_lowercase + string.ascii_uppercase

In [83]: alphabet.index('o')
Out[83]: 14

In [84]: alphabet[alphabet.index('o')+12]
Out[84]: 'A'

In [85]: alphabet[alphabet.index('O')+12]

结果IndexError: string index out of range。那是因为len(alphabet)是 52,并且

In [91]: alphabet.index('O')+12
Out[91]: 52

不知何故,我们需要 52 回绕到 0。您可以使用%模运算符来做到这一点:

In [92]: 52 % 52
Out[92]: 0
于 2012-10-31T02:55:41.957 回答