初知古典密码

键盘加密

(一)将给出的一堆没有意义的字符在键盘上比划,根据比划的形状确定密文。

  • 比如给出"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的字符串

aaaaaafaababkababapabbbbubabaazbbaab
baaaabgaabbalababbqbaaaavbabab
caaabahaabbbmabbaarbaaabwbabba
daaabbiabaaanabbabsbaabaxbabbb
eaabaajabaaboabbbatbaabbybbaaa

仿射加密

将明文与密钥的一部分相乘,再加上密钥的另一部分。

  • 将字母用数字表示,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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值