疯狂挑战:Python加密函数中的旋转字母

时间:2014-10-02 19:37:33

标签: python add letters

我正在尝试编写一个函数rot(c,n),将单个字符c向前旋转字母表中的n个点。

def rot(c,n):
""" rotate c forward by n characters,
    wrapping as needed; only letters change
"""

if 'a' <= c <= 'z':          # lower-case
    new_ord = ord(c) + n
    if new_ord > ord('z'):
        new_ord = new_ord - (2*n)
elif 'A' <= c <= 'Z':        # upper-case
    new_ord = ord(c) + n 
    if new_ord > ord('Z'):
        new_ord = new_ord - (2*n)

else:                        # non-alpha
    new_ord = ord(c)
return chr(new_ord)

但是我想要的输出如下:

>>> rot('a', 2)
'c'
>>> rot('y', 2)
'a'
>>> rot('A', 3)
'D'
>>> rot('Y', 3)
'B'
>>> rot('!', 4)
'!'

我一直收到错误的输出。有人能告诉我我做错了吗?

4 个答案:

答案 0 :(得分:2)

你的问题在这里:

new_ord = new_ord - (2*n)

这个想法是,当你超过z时,你必须完全删除整个字母,而不是删除你刚刚添加的两倍。

尝试:

new_ord = new_ord - 26

答案 1 :(得分:1)

两个班轮:(不要在家里试试)

def rot(c, n):
    start = 97 if c.islower() else 65 if c.isupper() else False      
    return chr((ord(c)-start+n)%26 + start) if start else c

答案 2 :(得分:0)

此版本还支持&#34;负旋转&#34 ;;我还将条件转换为.isupper().islower(),因为我发现它们更具可读性(并且更不容易出现一个错误):

def rot(c,n):
    """ rotate c forward by n characters,
        wrapping as needed; only letters change
    """
    new_ord = ord(c) + (n % 26)
    if c.isupper():
        if new_ord > ord('Z'):
            new_ord -= 26
        elif new_ord < ord('A'):
            new_ord += 26
        return chr(new_ord)
    elif c.islower():
        if new_ord > ord('z'):
            new_ord -= 26
        elif new_ord < ord('a'):
            new_ord += 26
        return chr(new_ord)
    return c

答案 3 :(得分:0)

Alternativly:

import string
from itertools import cycle

def make_rotation_tables(n):    
    uc, lc = map(cycle, (string.uppercase, string.lowercase))
    nchar = len(string.uppercase)
    part = slice(n, n + nchar)
    rotate = lambda n, it: ''.join(
        [next(it) for i in xrange(26+nchar)][part])
    rot_letters = ''.join(map(lambda x: rotate(n, x), [uc, lc]))    
    return string.maketrans(string.letters, rot_letters)

rottbl = make_rotation_tables(1)
print 'Caesar dixit: "Veni, vidi, vici!"'.translate(rottbl)
>>> Dbftbs ejyju: "Wfoj, wjej, wjdj!"