实验吧-密码学-杯酒人生(特殊凯撒--维吉尼亚密码)(凯撒加解密脚本、维吉尼亚密码加解密脚本)

99封情书 提交于 2021-02-13 14:05:06

题目:

使用古典密码
一喵星人要想喵星发送一段不知道干什么用的密码“BLOCKCIPHERDESIGNPRINCIPLE”,
但是它忘记了密钥是什么, 手头(爪头)只有它自己加密过的密钥“HTRUZYJW”, 而且它
还知道原密钥是一个单词, 你可以帮助它传递信息, 早日攻克蓝星, 征服人类吗?

 

已经提示要用古典密码,现在有两个字符串,一个是密码,一个是密钥。

密钥没加密前是一个单词,我们用凯撒解码,可以看到应该是COMPUTER

而这个密码在喵星人发送之前要进行加密,一串大写字母,而且这一串字母是:block cipher design principle

意思就是:分组密码设计原理

 

其实,这是一个特殊的凯撒:维吉尼亚密码

先介绍一下这个密码,该密码的加解密的对应表是由26个字母的所有凯撒解码组成。

A -A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
B -B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
C -C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
D -D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
E -E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
F -F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
G -G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
H -H I J K L M N O P Q R S T U V W X Y Z A B C D E F G
I -I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
J -J K L M N O P Q R S T U V W X Y Z A B C D E F G H I
K -K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
L -L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
M -M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
N -N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
O -O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
P -P Q R S T U V W X Y Z A B C D E F G H I J K L M N O
Q -Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
R -R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
S -S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
T -T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
U -U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
V -V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
W -W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
X -X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
Y -Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
Z -Z A B C D E F G H I J K L M N O P Q R S T U V W X Y
 

对于这个题来说,明文BLOCKCIPHERDESIGNPRINCIPLE,密钥COMPUTER,加密方法就是:

明文第一个是B,密钥第一个是C,于是就找在C开头的行中和B(第一行的字母)同一列的字母D。

循环使用COMPUTER将明文的对应字母全部找出。

下面给出py脚本:

代码转自:https://blog.csdn.net/dongyanwen6036/article/details/76716373

# encoding: utf-8

def VigenereEncryto(min,key):
	MinLen=len(min)#明文长度
	KeyLen=len(key)#密钥长度
	(q,r)=divmod(MinLen,KeyLen)#q商 r余数
	out=""
	#完整映射密钥的加密
	for i in range(0,q):
		for j in range(0,KeyLen):
		#谈谈核心代码理解结合实例
		#密钥:R
		#明文:T
		#密文:K:
		#(R-A)%26+A和(T-A)%26+A得到K===>(T-A+R-A)%26+A
		#(T-A)%26+A就是以A开头第T个元素,A与R列对齐意思即是,(R-A)%26+A就是以R头字母表,R之后的第T-A元素
			c=int((ord(min[i*KeyLen+j])-ord('A')+ord(key[j])-ord('A'))%26+ord('A'))
			out+=chr(c)
	#残余映射密钥加密
	for i in range(0,r):
		c=int((ord(min[q*KeyLen+i])-ord('A')+ord(key[i])-ord('A'))%26+ord('A'))
		out+=chr(c)
	return out
	
def VigenereDecryto(anwen,key):
	AnLen=len(anwen)#明文长度
	KeyLen=len(key)#密钥长度
	(q,r)=divmod(AnLen,KeyLen)#q商 r余数
	out=""
	#完整映射密钥的加密
	for i in range(0,q):
		for j in range(0,KeyLen):
		#已知暗文位置减去A,加上Z减去key的位置就是,A到明文长度
		#K-A+1   + Z-R===〉T-A
			c=int((ord(anwen[i*KeyLen+j])-ord('A')+1+ord('Z')-ord(key[j]))%26+ord('A'))
			out+=chr(c)
	#残余映射密钥加密
	for i in range(0,r):
		c=int((ord(anwen[q*KeyLen+i])-ord('A')+1+ord('Z')-ord(key[i]))%26+ord('A'))
		out+=chr(c)
	return out
def Lower(str):
	u=""
	for i in str:
		u+=i.lower()
	return u
 
if __name__=='__main__':
	num=input('选择维吉尼亚模式:1加密,2解密: ')
	if num=='1':
		str=input('请输入明文: ')
		key=input('请输入密钥: ')
		print('加密后的密文: '+VigenereEncryto(str,key))
		print('密文转化成小写: '+Lower(VigenereEncryto(str,key)))
	elif num=='2':
		str=input('请输入密文: ')
		key=input('请输入密钥: ')
		print('解密后的明文: '+VigenereDecryto(str,key))
		print('明文转化成小写: '+Lower(VigenereDecryto(str,key)))
	else:
		print('Error')

跑一下出来结果:DZAREVMGJSDSYLMXPDDXHVMGNS

 

顺带附上凯撒解码脚本:

#代码转自:https://blog.csdn.net/dongyanwen6036/article/details/76716373

#实现大小写字母并行平移
def change1(c,i):
	num=ord(c)
	if(num>=97 and num<=122):  
		num=97+(num+i-97)%(26)  
	return chr(num)
def change2(c,i):
	num=ord(c)
	if(num>=65 and num<=90):  
		num=65+(num+i-65)%(26)  
	return chr(num)	
 
      
def kaisa_jiAmi(string,i):  
	string_new=''  
	for s in string:
		num=ord(s)
		if(num>=97 and num<=122 ):
			string_new+=change1(s,i)
		elif(num>=65 and num<=90 ):
			string_new+=change2(s,i)
	print(string_new)  
	return string_new  
  
#本题有种暴力解密感觉  
def kaisa_jiEmi(string):  
	for i in range(0,26):  
		print('第'+str(i+1)+'种可能:',end='')
		#区别在于 string 是该对象原本就是字符串类型, 而 str()则是将该对象转换成字符串类型。  
		kaisa_jiAmi(string,i)  
          
#你要知道input输入的数据类型都是string     
def main():  
	print('请输入操作,注意默认小写,大写同理:')  
	choice=input('1:恺撒加密,2:凯撒穷举解密.请输入1或2:')  
	if choice=='1':  
		string=input('请输入需要加密字符串: ')  
		num=int(input('请输入需要加密的KEY: '))  
		kaisa_jiAmi(string,num)  
	elif choice=='2':  
		string=input('请输入需要解密字符串: ')  
		kaisa_jiEmi(string)  
	else:  
		print('输入错误,请重试')  
		main()  
          
if __name__=='__main__':  
	main()  

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!