无法弄清楚为什么我的字母在Python中的Caesar代码中没有旋转

时间:2017-10-27 10:02:01

标签: python caesar-cipher

我一直在研究这个问题已经有一个星期了,并且无法弄清楚为什么我的信件没有旋转。我不是在寻找有人为我做代码,而是帮我找出问题所在。基本上,我正在寻找一个橡皮鸭来帮助解决这个问题。我看到它旋转了最后一个字母而不是其余的字母。这就是我现在所处的位置。

from string import ascii_uppercase, ascii_lowercase

def caeser_encrypt(string, step):
    new_string = list(string)

    for i in range(len(new_string)):
        new_ascii = ord(new_string[i]) + step

    if string[i] in ascii_uppercase:
        if new_ascii > 90:
            new_ascii = new_ascii - 90 + 64
        elif new_ascii < 65:
            new_ascii = 91 - 65 - new_ascii

    if string[i] in ascii_lowercase:
        if new_ascii > 122:
            new_ascii = new_ascii - 122 + 96
        elif new_ascii < 97:
            new_ascii = 123 - 97 - new_ascii
        new_string[i] = chr(new_ascii)

    return ''.join(new_string)

def main ():
    string = input('Enter word(s)')
    step = input("How many rotations do you want?")
    step = int(step)

    print(caeser_encrypt(string, step))

if __name__ == "__main__":
    main()

2 个答案:

答案 0 :(得分:1)

由于此缩进,只旋转了最后一个字母:

dill

你的意图是:

for i in range(len(new_string)):
    new_ascii = ord(new_string[i]) + step

if string[i] in ascii_uppercase:
    if new_ascii > 90:
        new_ascii = new_ascii - 90 + 64
    elif new_ascii < 65:
        new_ascii = 91 - 65 - new_ascii

也就是说,for i in range(len(new_string)): new_ascii = ord(new_string[i]) + step if string[i] in ascii_uppercase: if new_ascii > 90: new_ascii = new_ascii - 90 + 64 elif new_ascii < 65: new_ascii = 91 - 65 - new_ascii 语句应该在if语句下缩进。 如果for语句没有缩进, 然后它们不会在循环中执行, 但只执行一次,在<{em> if循环后执行。 那时for被设置为最后一个字母的索引, 这就是为什么只旋转最后一个字母的原因。

代码审查

许多其他改进都是可能的。

而不是魔术数字,如90,65, 最好使用iord('z')

ord('a')if string[i] in ascii_uppercase是相互排斥的条件, 所以他们应该与if string[i] in ascii_lowercase链接在一起。

而不是elif, 在if string[i] in ascii_uppercase中执行线性搜索(检查ascii_uppercase中的每个值,直到找到匹配项为止), 使用范围检查会更有效率, ascii_uppercase

该实现也取代了非字母字符。 如果我要旋转“你好世界”, 这将产生一个有趣的结果, 因为空间。 也许这样就好了, 这样字界就无法区分了。 所以这不是批评,只是旁注。

把它放在一起, 以及其他一些小改进, 你可以这样写:

if 'A' <= string[i] <= 'Z'

答案 1 :(得分:0)

那里有几个缩进问题:

  1. for i in range(len(new_string)):循环只发生一件事,即设置new_ascii。当该循环结束时,i等于len(new_string) - 1,因此它将设置最后一个字符,但不设置任何其他字符。

  2. new_string[i] = chr(new_ascii)行是您的代码在新字符串中添加字母的位置,但请检查缩进 - 仅在if string[i] in ascii_lowercase:为真时才会发生,因此仅适用于小写字母。

  3. 这应该有效:

    def caeser_encrypt(string, step):
        new_string = list(string)
    
        for i in range(len(new_string)):
            new_ascii = ord(new_string[i]) + step
    
            if string[i] in ascii_uppercase:
                if new_ascii > 90:
                    new_ascii = new_ascii - 90 + 64
                elif new_ascii < 65:
                    new_ascii = 91 - 65 - new_ascii
    
            if string[i] in ascii_lowercase:
                if new_ascii > 122:
                    new_ascii = new_ascii - 122 + 96
                elif new_ascii < 97:
                    new_ascii = 123 - 97 - new_ascii
    
            new_string[i] = chr(new_ascii)
    
        return ''.join(new_string)