我想让用户输入一个字符串和一个值来向前或向后移动字符。我想让每个字符按用户输入的值+其在字符串中的位置向前移动。我想让它只对字母和数字生效,所以空格和符号不受影响。例如,如果用户输入 "5 "作为值,"a b c "作为字符串,我想把 "a "改为 "f";"b "改为 "i';"c "改为 "l"。因此,输出将是 "f i l"。
假设用户只会输入小写字母。
message = input("Enter your message: ")
for characters in message:
正如评论中所说,你所需要的是正确使用 ord()
和 chr()
的内置方法。此外,对于字母在字符串中的位置,你可以简单地使用 enumerate()
.
我会用这样的东西来实现。
def enc(s, n):
sign = 1 if n == abs(n) else -1
get_new_ord = lambda char, i: \
((ord(char) + n + sign * i - 96) % 26 or 26) + 96 if char.isalpha() \
else ((ord(char) + n + sign * i - 47) % 10 or 10) + 47
return "".join(chr(get_new_ord(char, i)) \
if char.isalpha() or char.isdigit() \
else char for i, char in enumerate(s))
这样你就可以直接调用 enc()
函数,通过 n
参数来设置每个字符要向前移动的数字,并使用 s
参数为字符串本身。
例如:
>>> enc('a b c', 5)
'f i l'
再往前推
>>> enc('f i l', -5)
'a b c'
复杂的加密和解密
>>> enc('alan touring 123, ada lovelace 456, rafael liscano 789', 15)
'pbrf njqogmg 913, hlj waisaqtw 024, qagchp rpalkya 357'
>>> enc('pbrf njqogmg 913, hlj waisaqtw 024, qagchp rpalkya 357', -15)
'alan touring 123, ada lovelace 456, rafael liscano 789'
现在,这里发生了什么?
首先我们得到的是 n
来确定我们要加密字符串的方向。当然,如果 n
数是正数,它的绝对值就会和自己一样,而且符号是1,否则就是负数(-1)。否则,就是负数(-1)。
那么我们定义 get_new_ord
来获取字符串中字符的新ascii值,将其向前或向后移动后。
为此,我们使用公式。
((ord(char) + n + sign * i - 96) % 26 or 26) + 96 # For letters
((ord(char) + n + sign * i - 47) % 10 or 10) + 47 # For numbers
# char: The character
# n: The the value the user enters
# i: The position of the character in the string
我们基本上是用模块运算符(%)来保持字符在ASCII表中所属的范围内. (48; 57代表数字,97; 122代表字母). 48;57为数字,97;122为字母),无论和值是 ord(char) + n + sign * i
. 这样一来,如果该操作的结果超出了上述ASCII值的边界,也没有关系,因为它会 "重置 "结果,直到它处于我们需要的值之间。
比如说
1000 % 26 + 96 = 108 # 1000 is way beyond the ASCII values for letters, but 108 is not
脚本的其余部分只是在字符串上迭代,调用加密函数以获得正确的字符,并将所有字符连接成一个新的字符串。
免责声明 我希望大家都能理解我的意思。原谅我的英语,我希望我可以解释得更好。
使用ord和chr对'a-z'或'0-9'范围内的字符进行处理。
编码
def encrypt(s, n): "根据旋转指数进行加密"
def limit(i, lower, upper):
interval = upper - lower + 1
while i > upper:
i -= interval
while i < lower:
i += interval
return i
def lookup(v, rotation):
o, c = ord(v), v.lower()
if 'a' <= c <= 'z':
ans = limit(o + rotation, ord('a'), ord('z'))
return chr(ans)
elif '0' <= c <= '9':
ans = limit(o + rotation, ord('0'), ord('9'))
return chr(ans)
return v
return ''.join([lookup(c, i+n) for i, c in enumerate(s)])
def decrypt(s, n): "n是加密时指定的旋转次数"
def limit(i, lower, upper):
interval = upper - lower + 1
while i > upper:
i -= interval
while i < lower:
i += interval
return i
def lookup(v, rotation):
o, c = ord(v), v.lower()
if 'a' <= c <= 'z':
ans = limit(o + rotation, ord('a'), ord('z'))
return chr(ans)
elif '0' <= c <= '9':
ans = limit(o + rotation, ord('0'), ord('9'))
return chr(ans)
return v
# n specifies the rotation specified by encryption
# rotate each letter by -(i + n) where i is it's position index
return ''.join([lookup(c, -(i+n)) for i, c in enumerate(s)])
测试
加密
print(encrypt('a b c', 5)) # f i l
print(encrypt('a b c d e 12 34', 5)) # f i l o r 68 13
print(encrypt('ab cd e 12 34', -5)) # vx ac f 46 91 (handles positive and negative rotation)
print(encrypt('a b c d e 1 2 3 4', 26)) # a d g j m 7 0 3 6 (even multiples of letter 26 are changed since rotation depends on letter position)
print(encrypt('abcde 1234', -26)) # acegi 1357
解密
加密文本的解密=>原文。
print(decrypt(encrypt('a b c', 5), 5)) # 'a b c'
print(decrypt(encrypt('a b c d e 12 34', 5), 5)) # 'a b c d e 12 34'
print(decrypt(encrypt('ab cd e 12 34', -5), -5)) # 'ab cd e 12 34'
print(decrypt(encrypt('a b c d e 1 2 3 4', 26), 26)) #'a b c d e 1 2 3 4'
print(decrypt(encrypt('abcde 1234', -26), -26)) # 'abcde 1234'