首页 > 其他分享 >playfair密码

playfair密码

时间:2024-10-20 14:09:39浏览次数:8  
标签:playfair index lsPlain 明文 密码 strText 字母 append

实验介绍:

playfair密码也是多表代换密码

一:编制密码表

playfair密码表是一个5x5的矩阵

密码表包括了所有26个字母
5x5等于25,那么多出的一个字母怎么办呢?
在规定中,字母i和j放入同一个格子
image

从左到右,从上到下把密钥填入矩阵,再按字母表顺序填入字母

矩阵已经有的字母不填入
image

二:格式化明文

将明文两个字母为一组分组

image

如果出现一组里两个字母相同的情况,在字母中间插入x

image

如果最后是奇数,我们还需要添加字母x

image

三:加密明文

如果一组明文在密码表的位置是对角线

对应的密文是对角线的镜像方向
明文wo 密文za ,w->z ,o->a
image

如果一组明文在密码表的位置是同一行

对应的密文是字母右移一位的字母
明文ai 密文na ,a->n , i -> a
image

如果一组明文在密码表的位置是同一列

对应的密文是字母下移一位的字母
明文gx 密文fg ,g->f , x -> g
image
明文:aoaizhongguo
密文:zanavmxofgfxxi

四:解密密文及python加密代码

解密密文就是把向下移动的改成向上移动,向右改成向左,对角线的还是镜像方向
加密代码

点击查看代码

#格式化明文,使相邻两个相同字母加入x,并凑成偶数个字符数
def FormatPlainText(strText):
	
	#strText.replace(" ","")
	top=len(strText)#获得明文的长度
	
	lsPlain=list()
	print("明文长度是:",top)
	if(top%2)==0:#even,当明文长度为偶数长,即可以完全配对,不需要在明文串末尾补充约定的字母
		for index in range(0,top,2):#range函数有3个参数的:第1个表示左边界,第2个表示右边界,第3个表示步长,含左不含右,即范围(也是index取值)为0,2,4,...,top-1
			if(strText[index]==strText[index+1]):#2个配对的字母相同,则需要在这2个字母之间添加一个字母“x”,再赋给新列表lsPlain
				lsPlain.append(strText[index])
				lsPlain.append('x')
				lsPlain.append(strText[index+1])
			else:#不同的配对字母直接赋给新列表lsPlain
				lsPlain.append(strText[index])
				lsPlain.append(strText[index+1])
				
		
	else:#odd,当明文长度为奇数长度,最后一个字符会单出来
		for index in range(0,top-1,2):#不包含最后一个字符
			if(strText[index]==strText[index+1]):#2个配对的字母相同,则需要在这2个字母之间添加一个字母“x”,再赋给新列表lsPlain
				lsPlain.append(strText[index])
				lsPlain.append('x')
				lsPlain.append(strText[index+1])
			else:#不同的配对字母直接赋给新列表lsPlain
				lsPlain.append(strText[index])
				lsPlain.append(strText[index+1])
		lsPlain.append(strText[top-1])
		
	if(len(lsPlain)%2)!=0:#若得到的列表lsPlain不是偶数长度,则在最后补充上约定的字符“x”
		lsPlain.append('x')
		
#	print("\nformated plain text:", " ".join(lsPlain))
	print("\n处理配对后的明文为:", " ".join(lsPlain))
	return lsPlain



#格式化秘钥,使消除重复字符,并添加后续a-z字母,同时使i,j当成i或j处理
def FormatKey(strKey):

	lsKey=list()
	strKeyLen=len(strKey)#获得密钥长度
	
	i=0

	#print("\nformating the orignal key...")
	while(i<strKeyLen):
		if lsKey.count(strKey[i])==0:#判断lsKey中有没有重复的strKey[i],如果没有,则strKey[i]作为新的字母附加到新密钥lsKey中
			lsKey.append(strKey[i])
		i+=1

	#print("\norginal key formated:","".join(lsKey))
	
	#print("\nstart to add a to z except j...")
	#下面的for循环时将26个英文字母中不在密钥strKey中的那些字母再附加到新密钥lsKey中
	for ch in range(ord('a'),ord('z')+1):#range函数有2个参数的:第1个表示左边界,第2个表示右边界,含左不含右,即ch取值范围是ord('a'),ord('b'),...,ord('z')26个数值
		if lsKey.count(chr(ch))==0:#判断ch对应的字符有没有重复的,没有重复的,直接赋到新密钥列表lsKey中,有重复的则不处理,即不加到lsKey新密钥列表中
			lsKey.append(chr(ch))
	
	#去掉j
	lsKey.remove('j')#移除列表lsKey中j值的第一个匹配项,即去除第一个j值,因为在刚刚上面的for循环里已经处理了重复的字母,所以这里就是将j字母从lsKey中去除
	print("\n处理的密钥25个字符为:"," ".join(lsKey))#处理后的lsKey是25个字母
	print("\n密钥长度为:",len(lsKey))
		
	return lsKey

def Cipher(lsMyKey,lsMyPlain):#用处理后的密钥lsMyKey对处理后的明文lsMyPlain进行加密
	
	lsResult=list()
	
	print("\n=============5*5密码表=========")
	for ch in lsMyKey:#将密钥lsMykey字符串处理得到对应的5*5密码表
		if(lsMyKey.index(ch)%5)==0:#每5个字符显示在一行
			print("")
#			print("\n")
		print(ch,end="   ")
	
	print("\n==================================\n 开始加密...\n")
		
	top=len(lsMyPlain)
	intCurrPre=intCurrNext=0
	intCurrPreRow=intCurrPreCol=0
	intCurrNextRow=intCurrNextCol=0
	intTempRow=intTempCol=intPos=0
	
	for index in range(0,top,2):
		intCurrPre=lsMyKey.index(lsMyPlain[index])#获得明文index位置上的字母值对应在密钥中的位置,当前还是针对一维的密钥串
		intCurrNext=lsMyKey.index(lsMyPlain[index+1])#获得明文index+1位置上字母值对应在密钥中的位置,当前还是针对一维的密钥串
		
		intCurrPreRow=intCurrPre//5#获得明文index位置上的字母值在二维密码表中的行值
		intCurrPreCol=intCurrPre%5#获得明文index位置上的字母值在二维密码表中的列值
		print("第",index,"个明文字母",lsMyPlain[index],",在密码一维表中位置为:",intCurrPre,",在密码二维表中行列值为(",intCurrPreRow,",",intCurrPreCol,")")
		
		intCurrNextRow=intCurrNext//5#获得明文index+1位置上的字母值在二维密码表中的行值
		intCurrNextCol=intCurrNext%5#获得明文index+1位置上的字母值在二维密码表中的列值
		print("第",index+1,"个明文字母",lsMyPlain[index+1],",在密码一维表中位置为:",intCurrNext,",在密码二维表中行列值为(",intCurrNextRow,",",intCurrNextCol,")\n")
		
		
		#1 same row,different col
		if(intCurrPreRow==intCurrNextRow) and (intCurrPreCol!=intCurrNextCol):#对相同行,不同列的2个字母进行加密
	#		print("same row,different column\n")
			print("配对的2个明文字母在相同行,不同列,将每个字母的同一行右边相邻的字母作为对应的密文:\n")
			#配对的第1个字符
			intTempCol=(intCurrPreCol+1)%5#获得相邻右边一列的列值
			intPos=intCurrPreRow*5+intTempCol#获取相邻右边一列字母在lsMyKey字符串中的实际位置

			print("得到的第",index,"个密文字母为",lsMyKey[intPos],",在密码一维表中位置为:",intPos,",在密码二维表中行列值为(",intCurrPreRow,",",intTempCol,")")
			lsResult.append(lsMyKey[intPos])#将获得的密文加到lsResult中
			# 配对的第2个字符
			intTempCol=(intCurrNextCol+1)%5
			intPos=intCurrNextRow*5+intTempCol
			print("得到的第",index+1,"个密文字母为",lsMyKey[intPos],",在密码一维表中位置为:",intPos,",在密码二维表中行列值为(",intCurrNextRow,",",intTempCol,")")
			lsResult.append(lsMyKey[intPos])
			
			print("===============================")
		
		#2 same column,different row
		if(intCurrPreRow!=intCurrNextRow) and (intCurrPreCol==intCurrNextCol):#对相同列,不同行的2个字母进行加密
#			print("same column,different row\n")
			print("配对的2个明文字母在相同列,不同行,将每个字母的同一列下边相邻的字母作为对应的密文:\n")
			#配对的第1个字符
			intTempRow=(intCurrPreRow+1)%5#获得相邻下边一行的行值
			intPos=intTempRow*5+intCurrPreCol#获得相邻下边一行字母在lsMyKey字符串中的实际位置
			print("得到的第",index,"个密文字母为",lsMyKey[intPos],",在密码一维表中位置为:",intPos,",在密码二维表中行列值为(",intTempRow,",",intCurrPreCol,")")
			lsResult.append(lsMyKey[intPos])
			#配对的第2个字符
			intTempRow=(intCurrNextRow+1)%5
			intPos=intTempRow*5+intCurrNextCol
			print("得到的第",index+1,"个密文字母为",lsMyKey[intPos],",在密码一维表中位置为:",intPos,",在密码二维表中行列值为(",intTempRow,",",intCurrNextCol,")")
			lsResult.append(lsMyKey[intPos])#将获得的密文加到lsResult中
			
			print("===============================")
			
			#3 different row,different col
		if(intCurrPreRow!=intCurrNextRow) and (intCurrPreCol!=intCurrNextCol):#对不同列,不同行的2个字母进行加密
#			print("different row,different column\n")
			print("配对的2个明文字母在不同行,不同列,配对字母各自所在行作为本方密文字母所在行,将配对字母各自所在列作为对方密文字母所在列:\n")
			#配对的第1个字符
			intTempCol=intCurrNextCol#获得配对的另一个字母所在列
			intPos=intCurrPreRow*5+intTempCol#获得本字母所在行,配对的另一字母所在列上对应的字符,即是本字母加密后的密文
			print("得到的第",index,"个密文字母为",lsMyKey[intPos],",在密码一维表中位置为:",intPos,",在密码二维表中行列值为(",intCurrPreRow,",",intTempCol,")")
			lsResult.append(lsMyKey[intPos])
			#配对的第2个字符
			intTempCol=intCurrPreCol#获得配对的另一个字母所在列
			intPos=intCurrNextRow*5+intTempCol#获得本字母所在行,配对的另一字母所在列上对应的字符,即是本字母加密后的密文
			print("得到的第",index+1,"个密文字母为",lsMyKey[intPos],",在密码一维表中位置为:",intPos,",在密码二维表中行列值为(",intCurrNextRow,",",intTempCol,")")
			lsResult.append(lsMyKey[intPos])
			
			print("===============================")
	print("加密结果为:","".join(lsResult))
	return lsResult

	


#main

txtPlain="woaizhongguo"
#txtPlain="Mysecretisinthetreeholes"

print("明文为:",txtPlain.lower())#

#txtKey="playfair"
txtKey="xiannong"
print("密钥为:",txtKey.lower())

lsNewPlain=FormatPlainText(txtPlain.lower())
#消除重复后添加后续字母,并且i,j都当成i处理
lsNewKey=FormatKey(txtKey.lower())

Cipher(lsNewKey,lsNewPlain)

标签:playfair,index,lsPlain,明文,密码,strText,字母,append
From: https://www.cnblogs.com/xiannong/p/18487159

相关文章

  • PbootCMS安装后,默认的后台用户名和密码是多少,怎么登陆?
    1.默认后台路径路径: http://您的域名/admin.php例如,如果你的域名是 example.com,则后台路径为 http://example.com/admin.php2.默认用户名和密码用户名: admin密码: 1234563.登录步骤打开浏览器:使用你喜欢的浏览器,如Chrome、Firefox等。输入后台......
  • PbootCMS修改后台登录账号和密码
    登录后台:使用当前的管理员账号和密码登录后台管理页面。修改密码:登录后,在右上角点击用户头像或用户名,通常会有一个下拉菜单。选择“修改密码”或类似的选项。在弹出的页面中,输入当前密码和新密码,然后保存。修改账号(可选):如果需要修改管理员账号,通常需要在后台的......
  • pbootcms如何修改后台的登陆地址/账号以及密码呢?
    修改后台登录地址步骤备份文件:在进行任何修改前,请先备份 admin.php 文件,以防止意外情况发生。备份命令示例(Linux):bash cp/path/to/your/project/admin.php/path/to/your/project/admin.php.bak重命名 admin.php 文件:将 admin.php 文件重命名为其他名......
  • PbootCMS后台访问地址及默认帐号密码
    1.后台访问路径路径: http://您的域名/admin.php例如,如果你的域名是 example.com,则后台访问路径为 http://example.com/admin.php2.默认帐号和密码用户名: admin密码: 1234563.登录步骤打开浏览器:使用你喜欢的浏览器,如Chrome、Firefox等。输入后......
  • 如何修改网站指定模板?网站怎么修改密码?
    修改网站指定模板通常涉及以下几个步骤,具体操作可能会根据使用的网站构建工具或平台(如WordPress,Joomla,Drupal等)有所不同:备份当前模板:在进行任何修改之前,确保备份当前正在使用的模板文件和数据库。这可以防止在修改过程中出现错误导致网站无法正常访问。选择编辑器:......
  • 网站后台密码修改工具?如何修改企业网站登录密码?
    创建一个网站后台密码修改工具涉及多个步骤,包括前端界面设计、后端逻辑处理以及数据库操作。数据库部分这里使用了一个简单的数组来模拟数据库。在实际应用中,你可能需要连接到真正的数据库,如MySQL、MongoDB等,并进行相应的操作。安全性考虑密码加密:使用bcrypt对密码进行加密存......
  • 修改帝国网站登录密码?网站被人修改了密码?
    修改帝国网站(如帝国CMS)的登录密码可以通过以下几种方式实现:通过后台管理界面修改:登录到帝国CMS的后台管理界面。进入“系统”->“系统设置”->“管理员密码修改”。按照提示输入新密码并保存。通过数据库直接修改:使用数据库管理工具(如phpMyAdmin)登录到你的数据库。......
  • 基于Multisim的密码锁的控制电路设计与仿真
    设计一个密码锁的控制电路,当输入正确代码时,输出开锁信号以推动执行机构工作,用红灯亮、绿灯熄灭表示关锁,用绿灯亮、红灯熄灭表示开锁;在锁的控制电路中储存一个可以修改的4位代码,当开锁按钮开关(可设置成6位至8位,其中实际有效为4位,其余为虚设)的输入代码等于储存代码时,开锁从第一......
  • 重置网站后台管理员密码方法
    重置网站后台管理员密码通常有几种方法,具体取决于网站或应用的架构和安全设置。下面是一些常见的方法:通过邮箱找回如果系统支持,可以通过注册时绑定的邮箱找回密码。一般会有一个“忘记密码”链接,点击后按照提示操作即可。数据库直接修改对于熟悉数据库操作的管理员来说......
  • 网站后台管理员如何修改?网站修改密码打不开?
    网站后台管理员如何修改登录后台管理系统使用管理员账号登录后台管理系统。进入管理员管理页面导航到管理员管理页面,通常在“系统设置”或“用户管理”中可以找到。编辑管理员信息找到需要修改的管理员账户,点击“编辑”按钮。修改管理员的用户名、密码、邮箱等......