任务描述
上关方法并不能正确处理所有小写英文字母,比如’y’偏移 2 位得到的是’{’。这是因为在 ASCII 编码表中,‘y’向后移动 2 位对应的字符就是’{’。而凯撒加密规定,如果偏移时超过了字符’z’,就重新从’a’开始,所以’y’偏移 2 位得到的应该是’a’。这种偏移方式称为循环偏移。
本关任务是利用循环偏移方式加密一个小写英文字母。
相关知识
循环偏移的实现
先不考虑 ASCII 码,给 26 个小写字母重新编号,‘a’~'z’的编号依次是 0~25。设某个字符 x 的编号是 xid,对 x 加密,就是 xid 加上偏移量 key。例如,‘a’偏移 2 位,就是 0 加上 2,得 2,第 2 号字符是’c’,‘a’的加密结果就是’c’。
如前所述,xid+key 的结果可能大于 25,即超过 ‘a’~‘z’ 的编号范围。例如,‘y’偏移 2 位,得到的编号是 26,而第 26 号字符是不存在的,需要将 26 变成 0,才能得到正确的偏移结果’a’。类似地,如果相加结果是 27,则要变为 1,如果是 28,则变为 2,等等,也就是实现下图所示的转换。
for i in range(0, 26*3):
yid = i%26
print('%d -> %d' % (i, yid))
这样就解决了循环偏移的问题。但是,上面的讨论基于的是字符编号,而在程序实现时需要使用字符的 ASCII 码。其实两者之间有对应关系,它们都是连续的整数,只不过编号是从 0 开始的,而 ASCII 码是从 97 开始,所以两者相差 97,而这个 97 就是首个字符’a’的 ASCII 码。
算法描述
从上面的讨论可得循环偏移对应的流程图,如下左图所示。如下右图给出的是字符’y’循环偏移 2 位的计算过程(即 x 的值是’y’,key 是 2)。
测试说明
测试集给出了所有小写英文字母及其对应的加密结果,可以看到,'y’和’z’能被正确加密。
a -> c
b -> d
c -> e
d -> f
e -> g
f -> h
g -> i
h -> j
i -> k
j -> l
k -> m
l -> n
m -> o
n -> p
o -> q
p -> r
q -> s
r -> t
s -> u
t -> v
u -> w
v -> x
w -> y
x -> z
y -> a
z -> b
开始你的任务吧,祝你成功!
firstASCII = ord('a') #首个字符的ASCII码,请在enChar中使用
N = 26 #支持的字符总数,请在enChar中使用
########## Begin ##########
def enChar(x, key):
xid = ord(x) - firstASCII
yid = (xid + key) % N
y = chr(firstASCII + yid)
return y
########## End ##########
key = 2 #密钥(也就是偏移量)
for x in 'abcdefghijklmnopqrstuvwxyz': #对于所有小写字母
y = enChar(x, key) #求x对应的密文字符
print('%s -> %s' % (x, y))
因篇幅问题不能全部显示,请点此查看更多更全内容