接收字母并将该字母向右旋转13位的Python函数

时间:2018-08-30 14:57:28

标签: python string input

我正在尝试创建一个使用Caesar密码对消息进行加密的Python函数。

到目前为止,我的代码是

letter = input("Enter a letter: ")
def alphabet_position(letter):
alphabet_pos = {'A':0, 'a':0, 'B':1, 'b':1, 'C':2, 'c':2, 'D':3,
                'd':3, 'E':4, 'e':4, 'F':5, 'f':5, 'G':6, 'g':6,
                'H':7, 'h':7, 'I':8, 'i':8, 'J':9, 'j':9, 'K':10,
                'k':10, 'L':11, 'l':11, 'M':12, 'm':12, 'N': 13,
                'n':13, 'O':14, 'o':14, 'P':15, 'p':15, 'Q':16,
                'q':16, 'R':17, 'r':17, 'S':18, 's':18, 'T':19,
                't':19, 'U':20, 'u':20, 'V':21, 'v':21, 'W':22,
                'w':22, 'X':23, 'x':23, 'Y':24, 'y':24, 'Z':25, 'z':25 }
pos = alphabet_pos[letter]
return pos  

当我尝试运行代码时,它将要求输入字母,但此后不返回任何内容

如有任何建议,请提供帮助。

5 个答案:

答案 0 :(得分:0)

您将需要以其他方式访问字典:

pos = alphabet_pos.get(letter)
return pos

然后您最终可以调用该函数。

alphabet_position(letter)

答案 1 :(得分:0)

您可以定义两个字典,一个字典与另一个字典相反。您需要注意以下几个方面:

  • 案例是否重要。如果不是,请使用str.casefold,如下所示。
  • 滚动字母末尾会发生什么情况,例如“ z”之后的第13个字母。下面我们假设您从头开始。
  • 请勿手动输入字母。您可以使用string模块。

这是一个演示:

letter = input("Enter a letter: ")

from string import ascii_lowercase

def get_next(letter, n):
    pos_alpha = dict(enumerate(ascii_lowercase))
    alpha_pos = {v: k for k, v in pos_alpha.items()}
    return pos_alpha[alpha_pos[letter.casefold()] + n % 26]

get_next(letter, 13)

Enter a letter: a
'n'

答案 2 :(得分:0)

如果您需要全新的编码字典

import string
import numpy as np, random
letters = string.ascii_uppercase
d=dict(zip(list(letters),range(0,len(letters))))
encoded_dic={}

def get_caesar_value(v, by=13):
    return(v+by)%26

for k,v in d.items():
    encoded_dic[k]=chr(65+get_caesar_value(v))
print(encoded_dic)

输出:

{'A': 'N', 'C': 'P', 'B': 'O', 'E': 'R', 'D': 'Q', 'G': 'T', 'F': 'S', 'I': 'V', 'H': 'U', 'K': 'X', 'J': 'W', 'M': 'Z', 'L': 'Y', 'O': 'B', 'N': 'A', 'Q': 'D', 'P': 'C', 'S': 'F', 'R': 'E', 'U': 'H', 'T': 'G', 'W': 'J', 'V': 'I', 'Y': 'L', 'X': 'K', 'Z': 'M'}

答案 3 :(得分:0)

您拥有的代码仅将字母映射到一个位置。我们将对其进行重写并创建一个rotate函数。

代码

import string
import itertools as it


LOOKUP = {
    **{x:i for i, x in enumerate(string.ascii_lowercase)},
    **{x:i for i, x in enumerate(string.ascii_uppercase)}
}


def abc_position(letter):
    """Return the alpha position of a letter."""
    return LOOKUP[letter]

def rotate(letter, shift=13):
    """Return a letter shifted some positions to the right; recycle at the end."""
    iterable = it.cycle(string.ascii_lowercase)
    start = it.dropwhile(lambda x: x != letter.casefold(), iterable)

    # Advance the iterator
    for i, x in zip(range(shift+1), start):
        res = x
    if letter.isupper():
        return res.upper()
    return res

测试

func = abc_position
assert func("a") == 0
assert func("A") == 0
assert func("c") == 2
assert func("z") == 25

func = rotate
assert func("h") == "u"
assert func("a", 0) == "a"
assert func("A", 0) == "A"
assert func("a", 2) == "c"
assert func("c", 3) == "f"
assert func("A", 2) == "C"
assert func("a", 26) == "a"
# Restart after "z"
assert func("z", 1) == "a"
assert func("Z", 1) == "A"

演示

>>> letter = input("Enter a letter: ")
Enter a letter: h
>>> rot = rotate(letter, 13)
>>> rot
'u'
>>> abc_position(rot)
20

在这里,我们将字母"h"旋转了13个位置,得到了一个字母,然后确定了该结果字母在abc的常规字符串中的位置。


详细信息

abc_position()

此函数被重写以查找字母的位置。它合并了两个字典:

  1. 一个枚举小写字母的字母
  2. 一个枚举大写字母的字母

string模块已经有这个字母了。

rotate()

此功能仅旋转小写字母;大写字母从小写位置转换。通过使无穷cycle(一个迭代器)的小写字母旋转字母字符串。

  1. 该循环首先以所需字母前进到start。这是通过删除所有看起来不像传入的字母来完成的。
  2. 然后将其循环前进,次数等于shift。循环只是消耗或向前移动迭代器的一种方法。我们只关心最后一个字母,而不关心中间的字母。该字母以小写或大写形式返回。

由于返回了字母(不是位置),因此您现在可以使用abc_position()函数来找到它的正常位置。

替代品

其他旋转功能可以代替rotate()

import codecs


def rot13(letter):
    return codecs.encode(letter, "rot13")

def rot13(letter):
    table = str.maketrans( 
        "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz", 
        "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")
    return str.translate(letter, table)

但是,这些选项仅限于rot13,而rotate()可以移动任意数字。注意:rot26将循环回到开头,例如rotate("a", 26) -> a

另请参阅this post,了解如何制作真正的rot13密码。

另请参阅itertools.cycleitertools.dropwhile上的文档。

答案 4 :(得分:-2)

您可以改为通过ordchr函数进行快速计算:

def encrypt(letter):
    return chr((ord(letter.lower()) - ord('a') + 13) % 26 + ord('a'))

这样:

print(encrypt('a'))
print(encrypt('o'))

输出:

n
b
相关问题