ROT-13 加密,英文字母表的13位移位
两次加密结果相同,即密文用相同方法二次加密可得明文,类凯撒加密。
以下是初次尝试用代码编写,后来在找有没有能自己生成lookup-tuple的方法,手动写真的有点蠢。
# ROT13 解密
# ABCD EFGH IJKL MNOP QRSTUVWXYZabcdefghijklmnopqrstuvwxyz
# NOPQ RSTU VWXY ZABC DEFGHIJKLMnopqrstuvwxyzabcdefghijklm
lookup_tuple = {'A':'N','B':'O','C':'P','D':'Q','E':'R','F':'S','G':'T',
'H':'U','I':'V','J':'W','K':'X','L':'Y','M':'Z','N':'A','O':'B',
'P':'C','Q':'D','R':'E','S':'F','T':'G','U':'H','V':'I','W':'J','X':'K',
'Y':'L','Z':'M','a':'n','b':'o','c':'p','d':'q','e':'r','f':'s','g':'t',
'h':'u','i':'v','j':'w','k':'x','l':'y','m':'z','n':'a','o':'b','p':'c',
'q':'d','r':'e','s':'f','t':'g','u':'h','v':'i','w':'j','x':'k','y':'l','z':'m'}
a = "Zl anzr vf n-wva , V yvxr fghql!"
c = ""
for i in a:
if i not in lookup_tuple:
b = i
else:
b = lookup_tuple[i]
c = c + b
print(c)
之后了解到string模块,查看源码可知:
"""A collection of string constants.
Public module variables:
whitespace -- a string containing all ASCII whitespace
ascii_lowercase -- a string containing all ASCII lowercase letters
ascii_uppercase -- a string containing all ASCII uppercase letters
ascii_letters -- a string containing all ASCII letters
digits -- a string containing all ASCII decimal digits
hexdigits -- a string containing all ASCII hexadecimal digits
octdigits -- a string containing all ASCII octal digits
punctuation -- a string containing all ASCII punctuation characters
printable -- a string containing all ASCII characters considered printable
"""
__all__ = ["ascii_letters", "ascii_lowercase", "ascii_uppercase", "capwords",
"digits", "hexdigits", "octdigits", "printable", "punctuation",
"whitespace", "Formatter", "Template"]
import _string
# Some strings for ctype-style character classification
whitespace = ' \t\n\r\v\f'
ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'
ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ascii_letters = ascii_lowercase + ascii_uppercase
digits = '0123456789'
hexdigits = digits + 'abcdef' + 'ABCDEF'
octdigits = '01234567'
punctuation = r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
printable = digits + ascii_letters + punctuation + whitespace
于是使用里面定义的ascii_lowercase和ascii_uppercase。
修改后代码:
import string
# 引入string的定义字符串
ascii_lowercase = string.ascii_lowercase # 小写字符串
ascii_uppercase = string.ascii_uppercase # 大写字符串
lookup_tuple = {} # 存放字典
# 大写字符串填充
for i in range(len(ascii_uppercase)):
lookup_tuple[ascii_uppercase[i]] = ascii_uppercase[i-13]
print(lookup_tuple)
# 小写字符串填充
for i in range(len(ascii_lowercase)):
lookup_tuple[ascii_lowercase[i]] = ascii_lowercase[i-13]
print(lookup_tuple)
# 输入
in_string = "Zl anzr vf n-wva , V yvxr fghql!"
c = ""
# 转换字母
for i in in_string:
if i not in lookup_tuple:
b = i
else:
b = lookup_tuple[i]
c = c + b
# 输出
print(c)
尝试其余rot 算法
ROT5:只对数字进行编码,将数字往前数的第5个数字替换当前数字,例如当前为0,编码后变成5,当前为1,编码后变成6。
ROT13:只对字母进行编码,将字母往前数的第13个字母替换当前字母,例如当前为A,编码后变成N,当前为B,编码后变成O。
ROT18:将ROT5和ROT13组合在一起,命名为ROT18。
ROT47:对数字、字母、常用符号进行编码,按ASCII值进行位置替换,将字符ASCII值往前数的第47位对应字符替换当前字符,例如当前为小写字母z,编码后变成大写字母K,当前为数字0,编码后变成符号_。用于ROT47编码的字符其ASCII值范围是33-126,具体参考ASCII编码。
----ps:懒得写成函数的作者
# ROT5、13、18 解密
import string
# 引入string的定义字符串
ascii_lowercase = string.ascii_lowercase # 小写字符串
ascii_uppercase = string.ascii_uppercase # 大写字符串
digits = string.digits
# rot-18
# ROT18:这是一个异类,本来没有,它是将ROT5和ROT13组合在一起,为了好称呼,将其命名为ROT18。
# rot-5
# ROT5:只对数字进行编码,用当前数字往前数的第5个数字替换当前数字,例如当前为0,编码后变成5,当前为1,编码后变成6,以此类推顺序循环。
digits_dict = {}
for i in range(len(digits)):
digits_dict[digits[i]] = digits[i-5]
# rot-13
# ROT13:只对字母进行编码,用当前字母往前数的第13个字母替换当前字母,例如当前为A,编码后变成N,当前为B,编码后变成O,以此类推顺序循环。
lookup_dict = {}
# 大写字符串填充
for i in range(len(ascii_uppercase)):
lookup_dict[ascii_uppercase[i]] = ascii_uppercase[i-13]
# 小写字符串填充
for i in range(len(ascii_lowercase)):
lookup_dict[ascii_lowercase[i]] = ascii_lowercase[i-13]
# 判断输入是否为数字、字母 后转换
# 这里有一个很有意思的发现:中文被if判断为alpha
cipher = input("what's your cipher str:")
clear = ''
for i in cipher:
if i.isdigit():
a_digit = digits_dict[i]
elif i.isalpha():
a_digit = lookup_dict[i]
else:
a_digit = i
clear += a_digit
print(clear)
# rot-47 解密
s = "nihao"
x = []
for i in range(len(s)):
j = ord(s[i]) # 字符在ASCII中的序号
if j >= 33 and j <= 126: # 用于ROT47编码的字符其ASCII值范围是33-126
x.append(chr(33 + ((j + 14) % 94)))
else:
x.append(s[i])
a = "".join(x)
print(a)