键盘加密
(一)将给出的一堆没有意义的字符在键盘上比划,根据比划的形状确定密文。
- 比如给出"BHUK,",在键盘上比划就可大致得到一个大写的'N'
- 或者给出"ljm,io",在键盘上比划就可发现这段字符将'k'圈起来了,则'k'即为所得
(二)利用键盘上数字和字母对应的列值和行值来加密
- 字母行值作为横坐标,数字列值作为纵坐标。如明文"bye"加密后的密文为"35 16 13"。
- 数字列值作为横坐标,字母行值作为纵坐标。明文"bye"加密后的密文为"53 61 31"。
小坑:行值还可以为两位数,如密文"111"可表示第1行,第11列对应的字符,即为'{'。
Brain Fuck(BF)和Ook密码
- BF密码是用><+-.,[]八种符号来替换c语言的各种语法和命令
- Ook三种符号组成:Ook.、Ook!、Ook?(简化的Ook:把Ook省略)
摩斯密码
由.和-组成(题目可能会把.和-换成其它字符)
凯撒密码
将每个字母按照字母表,向前或向后移动给定数目个位置,非字母字符不变。移动的数目就是密钥,故凯撒密码共有25种密钥。
脚本
(一)
#区分大小写
#不是大小写字母就原样输出
#自动分析解出的明文中是否有flag,ctf,key,the,is,no,for等关键字,并可由用户选择是否要由程序推荐明文
txt = input('请输入要解密的密文:').strip()
n = input('需要为您推荐明文吗(Y/N)').strip().lower()
print()
#遍历25种密钥
for i in range(1,26):
plain = ''
for j in txt:
if j.islower():
plain = plain + chr(97+(ord(j)-i-97)%26)
elif j.isupper():
plain = plain + chr(97+(ord(j)-i-65)%26)
else:
plain = plain + j
if n.lower() == 'y':
key = ('flag', 'ctf', 'key', 'the', 'is', 'no', 'for')#可能的关键字
for m in plain:
if m in key:
print('密文可能是', plain)
print()
break
elif n.lower() == 'n':
print(plain)
print()
print(plain,end='\n')
(二)
txt = input().strip()
lower = 'abcdefghijklmnopqrstuvwxyz'
upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i in range(1,26):
xiao = lower[i:]+lower[:i]#即为原顺序小写字母进行移动密钥个数位后的密文
da = upper[i:]+upper[:i]#即为原顺序大写字母进行移动密钥个数位后的密文
plain = ''
table = "".maketrans(xiao+da,lower+upper)
for j in txt:
plain = plain+j.translate(table)
print(plain)
print()
可能会产生变体,即每个字符的移位数是不同的,可能ASCII码值的移位数依次增大一或减小一或其它值,这是需要将关键字,如ctf、flag与密文一一对应,将ASCII码值写出,得到规律。
ROT13密码
凯撒的变体,密钥固定为13,效果是将前半部分和后半部分交换
移位密码
不仅处理字母,还会处理数字和特殊字符,常用ASCII码进行移位。可根据flag{}来确定移动位数。
培根密码
密文字符只有a和b,每个明文字符都会被替换为一个由a和b组成的长度为5的字符串
a | aaaaa | f | aabab | k | ababa | p | abbbb | u | babaa | z | bbaab |
b | aaaab | g | aabba | l | ababb | q | baaaa | v | babab | ||
c | aaaba | h | aabbb | m | abbaa | r | baaab | w | babba | ||
d | aaabb | i | abaaa | n | abbab | s | baaba | x | babbb | ||
e | aabaa | j | abaab | o | abbba | t | baabb | y | bbaaa |
仿射加密
将明文与密钥的一部分相乘,再加上密钥的另一部分。
- 将字母用数字表示,a=0,b=1.....z=25
- 两个密钥a和b,取值都是0~25
- a要求与26互质,如26的因数有1,2,13,那么a的因素不包括2和13就行
加密公式:密文 =(a*明文+b)%26
解密公式:明文 =a的负一次方*(密文-b)%26 , a的负一次方为a的乘法逆元,(不除以a是因为可能会得到小数)
假如用m来表示a的乘法逆元,可以这样来求m
m = 1
while True:
if a*m%26 == 1
print(m)
break
m = m + 1
猪圈密码
多表替换
维吉尼亚密码
明文:I love you
密钥:abc(对应0,1,2的移动位数,循环使用)
密文:I mqvf aov
txt = input('请输入密文:')
password = input('请输入密钥:').lower()
key = [ord(i) for i in password]
flag = ''
for i in range(len(txt)):
if txt[i].islower():
flag = flag + chr(97+(ord(txt[i])-97-key[i%len(key)])%26)#i%len(key)的作用是循环密钥
elif txt[i].isupper():
flag = flag + chr(65+(ord(txt[i])-65-key[i%len(key)])%26)
print(flag)
费纳姆密码
明文和密钥都要转换为7位二进制数,然后对应进行异或运算
解密只需要将密文与密钥进行异或运算,再转换为ASCII
栅栏密码
将明文分成n个一组(每一组的长度相同),然后依次把每组的第一/二...个字符连接起来。
def zhalan(txt,key):
s = ''
for m in range(0,key):
for n in range(m,len(txt),key):
s = s + txt[n]
return s
txt = input("请输入明文").strip()
key = []
for i in range(2,len(txt)):#找到可分的组数n
if len(txt)%i == 0:
key.append(i)
for j in key:
flag = zhalan(txt,j)
print(flag)
变体:W型
对字符串‘123456789’,若key=3
则每一组分别为:159、2468、37(每一组数量不一定相同)
故密文为:159246837
新知:
幂数加密
来源:攻防世界
基本原理:首先这一串数中仅有0,1,2,4,8
以0为分隔符,分成:
以1-26来代替A-Z,以该题为例,总共分成了8组,则共有8个字母。然后对每组进行翻译:可以用加法来表示0-9中任意一个数字,满足其和不大于26即可,如122可为1(2+2)->14或1+2+2->5,但不为(1+2)2->32(比26大),故122可表示E或L,如果有多种表示方法,先记下看别的即可。
综上,该题可表示为:W E/L L L D O N E/L,稍加分析可以知道应该是WELLDONE。