为什么这个替换密码脚本不断抛出错误?

Why does this substitution cipher script keep throwing an error?

我是 python 的新手,请多多包涵。我正在拼凑一个小密码谜题,其中一部分需要替换密码。在这种情况下,每个字母都被三个随机字母替换。每次我 运行 此代码在我尝试加密某些内容时都会抛出错误:

Traceback (most recent call last):
File "/home/pi/Desktop/expansion cipher.py", line 159, in <module>
crypt()
File "/home/pi/Desktop/expansion cipher.py", line 142, in crypt
print encrypt(txt)
File "/home/pi/Desktop/expansion cipher.py", line 127, in encrypt
ctxt = ctxt + exp_ciph(ptxt[counter])
File "/home/pi/Desktop/expansion cipher.py", line 121, in exp_ciph
return cur_exp
UnboundLocalError: local variable 'cur_exp' referenced before assignment

这是我的代码:

def rev_ciph(char):
    if char == "gps":
        cur_rev = "_"
    if char == "evl":
        cur_rev = "."
    if char == "jkb":
        cur_rev = "e"
    if char == "bhj":
        cur_rev = "t"
    if char == "szk":
        cur_rev = "a"
    if char == "nwu":
        cur_rev = "o"
    if char == "dpl":
        cur_rev = "i"
    if char == "sbg":
        cur_rev = "n"
    if char == "dsl":
        cur_rev = "s"
    if char == "yhq":
        cur_rev = "p"
    if char == "sav":
        cur_rev = "h"
    if char == "gfs":
        cur_rev = ","
    if char == "rtg":
        cur_rev = "d"
    if char == "fqu":
        cur_rev = "l"
    if char == "rjt":
        cur_rev = "u"
    if char == "sbv":
        cur_rev = "c"
    if char == "yqm":
        cur_rev = "m"
    if char == "ywh":
        cur_rev = "f"
    if char == "drt":
        cur_rev = "y"
    if char == "zfd":
        cur_rev = "w"
    if char == "asn":
        cur_rev = "g"
    if char == "fzj":
        cur_rev = "p"
    if char == "rka":
        cur_rev = "b"
    if char == "kzv":
        cur_rev = "v"
    if char == "lah":
        cur_rev = "k"
    if char == "rma":
        cur_rev = "x"
    if char == "fqn":
        cur_rev = "q"
    if char == "vrq":
        cur_rev = "j"
    if char == "tfv":
        cur_rev = "z"
    return cur_rev

def exp_ciph(char):
    if char == "_":
        cur_exp = "gps"
    if char == ".":
        cur_exp = "evl"
    if char == "e":
        cur_exp = "jkb"
    if char == "t":
        cur_exp = "bhj"
    if char == "a":
        cur_exp = "szk"
    if char == "o":
        cur_exp = "nwu"
    if char == "i":
        cur_exp = "dpl"
    if char == "n":
        cur_exp = "sbg"
    if char == "s":
        cur_exp = "dsl"
    if char == "p":
        cur_exp = "yhq"
    if char == "h":
        cur_exp = "sav"
    if char == ",":
        cur_exp = "gfs"
    if char == "d":
        cur_exp = "rtg"
    if char == "l":
        cur_exp = "fqu"
    if char == "u":
        cur_exp = "rjt"
    if char == "c":
        cur_exp = "sbv"
    if char == "m":
        cur_exp = "yqm"
    if char == "f":
        cur_exp = "ywh"
    if char == "y":
        cur_exp = "drt"
    if char == "w":
        cur_exp = "zfd"
    if char == "g":
        cur_exp = "asn"
    if char == "p":
        cur_exp = "fzj"
    if char == "b":
        cur_exp = "rka"
    if char == "v":
        cur_exp = "kzv"
    if char == "k":
        cur_exp = "lah"
    if char == "x":
        cur_exp = "rma"
    if char == "q":
        cur_exp = "fqn"
    if char == "j":
        cur_exp = "vrq"
    if char == "z":
        cur_exp = "tfv"
    return cur_exp

def encrypt(ptxt):
    ctxt = "Ciphertext: "
    counter = 0
    while counter <= len(ptxt):
        ctxt = ctxt + exp_ciph(ptxt[counter])
        counter += 1
    return ctxt

def decrypt(ctxt):
    ptxt = "Plaintext: "
    counter = 0
    while counter <= len(ctxt):
        ptxt = ptxt + rev_ciph(ctxt[counter])
        counter += 1
    return ptxt

def crypt():
    print
    txt = raw_input("Plaintext: ")
    print encrypt(txt)
    print

def ucrypt():
    print
    txt = raw_input("Ciphertext: ")
    print decrypt(txt)
    print

ex_code = False
while ex_code == False:
    print "(1) Encrypt"
    print "(2) Decript"
    print "(3) Exit"
    print
    mchoc = raw_input("What would you like to do(1,2,3?): ")
    if mchoc == "1":
        crypt()
    if mchoc == "2":
        ucrypt()
    if mchoc == "3":
        ex_code = True
    print

你有两个问题。首先是您没有处理所有可能的输入。刚刚复制并测试了您的代码后,我看到当且仅当您尝试加密包含 exp_ciph(char)(或 rev_ciph(char)那件事)。例如,这些函数都不处理大写字母。 Python 始终区分大小写,并将大写字母和小写字母视为完全不同的字符。您的函数也不处理其他字符,例如“,”和“;”。如果您为程序提供一个要加密的字符串,其中包含前两个函数未处理的字符,那么,当该字符出现时,这些函数中 if 语句的所有条件都为假,因此 cur_exp 永远不会被创建和赋值。当其中一个函数尝试 return cur_exp 时,它发现 cur_exp 不存在。这就是您上面描述的错误的来源。

如果您输入的字符串仅由小写字母和可能的“_”组成,则会出现完全不同的错误,即:

IndexError: string index out of range

这是因为函数 encrypt(ptxt) 总是寻找比字符串多一个字符。在 Python(而且,我认为,每一种编程语言)中,可迭代对象(例如字符串或列表)中的元素是通过它们从第一项开始的 OFFSET 进行索引的;也就是说,它前面有多少项。因此,如果您有一个包含 4 个字符的字符串 foo

foo = "abcd"

然后:

foo[0] == "a"
foo[1] == "b"
foo[2] == "c"
foo[3] == "d"

没有foo[4]。调用 foo[4] 将恰好引发上述错误。 len(object) 函数 returns 迭代中的项目数。因此,与上面的示例保持一致,

len(foo) == 4

因此调用

foo[len(foo)]

将加注 IndexError:。这正是您的 encrypt(ptxt) 函数中经常发生的事情

counter = 0
while counter <= len(ptxt):
    ctxt = ctxt + exp_ciph(ptxt[counter])
    counter += 1

你会想要这样做:

counter = 0
while counter <= len(ptxt) - 1:
    ctxt = ctxt + exp_ciph(ptxt[counter])
    counter += 1

这是我遇到的前两个问题运行。我不保证没有更多。希望这能让你走得更远。