-1

我目前正在做一个使用 rot 13 加密文本的作业,但我的一些文本不会注册。

# cgi is to escape html
# import cgi

def rot13(s):
    #string encrypted
    scrypt=''
    alph='abcdefghijklmonpqrstuvwxyz'
    for c in s:
        # check if char is in alphabet
        if c.lower() in alph:
            #find c in alph and return its place
            i = alph.find(c.lower())

            #encrypt char = c incremented by 13
            ccrypt = alph[ i+13 : i+14 ]

            #add encrypted char to string
            if c==c.lower():
                scrypt+=ccrypt
            if c==c.upper():
                scrypt+=ccrypt.upper()

        #dont encrypt special chars or spaces
        else:
            scrypt+=c

    return scrypt
    # return cgi.escape(scrypt, quote = True)


given_string = 'Rot13 Test'
print rot13(given_string) 

输出:

13 r
[Finished in 0.0s]
4

5 回答 5

2

嗯,似乎一堆东西都不起作用。主要问题应该在于:如果,例如,等于,那么您将ccrypt = alph[ i+13 : i+14 ]丢失 a ,那么您将超出列表边界。实际上,在您的输出中, only被编码为,因为它是测试字符串中唯一一个移动 13 并不会超出边界的字母。% len(alph)i18er

这个答案的其余部分只是稍微清理代码的提示:

  • 而不是alph='abc..你可以import string在脚本的开头声明一个并使用string.lowercase
  • 而不是使用字符串切片,最好只使用一个字符string[i],完成工作
  • 而不是c == c.upper(),您可以使用内置函数if c.isupper() ...
于 2012-12-12T23:43:32.507 回答
2

你遇到的麻烦是你的切片。如果您的角色在字母表的后半部分,它将是空的,因为i+13将不在末尾。有几种方法可以解决它。

最简单的可能是简单地将您的字母字符串加倍(字面意思是:)alph = alph * 2。这意味着您可以访问最多 52 个值,而不仅仅是最多 26 个。不过,这是一个非常粗略的解决方案,最好只修复索引。

更好的选择是从索引中减去 13,而不是添加 13。Rot13 是对称的,因此两者将具有相同的效果,并且它会起作用,因为负索引在 Python 中是合法的(它们指的是从末尾倒数的位置)。

在任何一种情况下,实际上都没有必要进行切片。您可以简单地获取单个值(与 C 不同,charPython 中没有类型,因此单个字符也是字符串)。如果您只进行此更改,它可能会说明您当前代码失败的原因,因为尝试访问字符串末尾的单个值会引发异常。

编辑:实际上,在考虑了真正最好的解决方案之后,我倾向于建议完全避免基于索引数学的解决方案。更好的方法是使用 Python 出色的字典来进行从原始字符到加密字符的映射。您可以像这样构建和使用 Rot13 字典:

alph="abcdefghijklmnopqrstuvwxyz"
rot13_table = dict(zip(alph, alph[13:]+alph[:13])) # lowercase character mappings
rot13_table.update((c.upper(),rot13_table[c].upper()) for c in alph) # upppercase

def rot13(s):
    return "".join(rot13_table.get(c, c) for c in s) # non-letters are ignored
于 2012-12-12T23:44:00.087 回答
1

这条线

ccrypt = alph[ i+13 : i+14 ]

不会做你认为它做的事 - 它从i+13to返回一个字符串切片i+14,但如果这些索引大于字符串的长度,切片将为空:

"abc"[5:6] #returns ''

这意味着您的解决方案将所有内容从n开始转换为空字符串,从而产生您观察到的输出。

实现这一点的正确方法是 (1.) 使用模运算将索引限制为有效数字和 (2.) 使用简单的字符访问而不是字符串切片,这更容易阅读、更快并抛出一个IndexErrorfor无效索引,这意味着您的错误很明显。

ccrypt = alph[(i+13) % 26]
于 2012-12-12T23:43:49.357 回答
1

可能给你带来一些问题的第一件事 - 你的字符串列表有no切换,所以你需要调整它:) 至于算法,当你运行时:

ccrypt = alph[ i+13 : i+14 ]

想想当你25从第一次迭代(for z)中返回时会发生什么。您现在正在寻找索引位置alph[38:39](旁注:您实际上可以说alph[38]),它远远超出了 26 个字符的字符串的边界,它将返回''

In [1]: s = 'abcde'

In [2]: s[2]
Out[2]: 'c'

In [3]: s[2:3]
Out[3]: 'c'

In [4]: s[49:50]
Out[4]: ''

至于如何修复它,有许多有趣的方法。您的代码只需稍作修改即可正常运行。您可以做的一件事是创建一个已经“旋转”了 13 个位置的字符映射:

alph = 'abcdefghijklmnopqrstuvwxyz'
coded = 'nopqrstuvwxyzabcdefghijklm'

All we did here is split the original list into halves of 13 and then swap them - we now know that if we take a letter like a and get its position (0), the same position in the coded list will be the rot13 value. As this is for an assignment I won't spell out how to do it, but see if that gets you on the right track (and @Makoto's suggestion is a perfect way to check your results).

于 2012-12-12T23:44:10.163 回答
-2

If you're doing this as an exercise for a course in Python, ignore this, but just saying...

>>> import codecs
>>> codecs.encode('Some text', 'rot13')
'Fbzr grkg'
>>> 
于 2017-09-17T00:43:27.553 回答