我正在尝试创建一个使用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
当我尝试运行代码时,它将要求输入字母,但此后不返回任何内容
如有任何建议,请提供帮助。
答案 0 :(得分:0)
您将需要以其他方式访问字典:
pos = alphabet_pos.get(letter)
return pos
然后您最终可以调用该函数。
alphabet_position(letter)
答案 1 :(得分:0)
您可以定义两个字典,一个字典与另一个字典相反。您需要注意以下几个方面:
str.casefold
,如下所示。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()
此函数被重写以查找字母的位置。它合并了两个字典:
string
模块已经有这个字母了。
rotate()
此功能仅旋转小写字母;大写字母从小写位置转换。通过使无穷cycle
(一个迭代器)的小写字母旋转字母字符串。
start
。这是通过删除所有看起来不像传入的字母来完成的。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.cycle
和itertools.dropwhile
上的文档。
答案 4 :(得分:-2)
您可以改为通过ord
和chr
函数进行快速计算:
def encrypt(letter):
return chr((ord(letter.lower()) - ord('a') + 13) % 26 + ord('a'))
这样:
print(encrypt('a'))
print(encrypt('o'))
输出:
n
b