信息安全-1:python之playfair密码算法详解[原创]

转发注明出处: http://www.cnblogs.com/0zcl/p/6105825.html

一、基本概念

  1. 古典密码是基于字符替换的密码。加密技术有:Caesar(恺撒)密码、Vigenere(维吉尼尔)密码、Playfair密码、Hill密码……
  2. 明文:未经过加密的信息;密文:加密后的信息
  3. 加密解密的过程:如下图

二、Caesar密码

  这里我先简单讲下恺撒密码,咸觉挺简单的,后面再主要讲Playfair算法原理与编程。

基本原理:

在开拓罗马帝国的时候,恺撒担心信使会阅读他送给士兵的命令,因此发明了对命令进行加密的算法--恺撒密码器

恺撒密码器挺简单的:把字母表中的每个字母向前循环移动3位

  • 加密信息将字母向前移动三位
  • 解密信息将字母向后移动三位
  • 移动的位数是关键,称之为密钥
  • 加密和解密的密钥是相同的,我们称之为对称密码器

数学表达

恺撒密码的加密算法表示为:C=E(p)=(p+3) mod 26

恺撒密码的解密算法表示为:p=D(C)=(C-3) mod 26

改进的恺撒密码

明文的发送方和接收方事先协商好一个密钥K(1<=K<=25),则:

恺撒密码的加密算法表示为:C=E(p)=(p+K) mod 26

恺撒密码的解密算法表示为:p=D(C)=(C-K) mod 26

三、Playfair密码

基本原理

Playfair算法基于一个5*5的字母矩阵,该矩阵使用一个关键词构造,方法是按从左到右、从上到下顺序,填入关键词的字母(去除重复字母)后,将字母表其作余字母填入。

例如: 关键词取:monarchy时,字母矩阵为下图如示(矩阵只能放25个字母,I与J同)

加密规则(重要)

Playfair加密算法是先将明文按两个字母一组进行分组,然后在矩阵中找对应的密文。

取密文的规则如下:

  1. 若明文出现相同字母在一组,则在重复的明文字母中插入一个填充字母(eg:z)进行分隔后重新分组(eg: balloon被重新分组为ba lz lo on)
  2. 若分组到最后一组时只有一个字母,则补充字母z
  3. 若明文字母在矩阵中同行,则循环取其右边下一个字母为密文(矩阵最右边的下一个是最左边的第一个)(eg: ar被加密为RM)
  4. 若明文字母在矩阵中同列,则循环取其下边下一个字母为密文(矩阵最下边的下一个是最上边的第一个)(eg: mu被加密为CM)
  5. 若明文字母在矩阵中不同行不同列,则取其同行且与同组另一字母同列的字母为密文(eg: hs被加密为BP,ea被加密为IM或JM)

PS:上述规则第一次看时挺烦的,但照着例子看就一定可以看懂的!

举例(这个例子后面测试会用到的):

明文为we are discovered save yourself,分组成为we ar ed is co ve re ds av ey ou rs el fz;

用上述矩阵加密后的密文为:UG RM KC SX HM UF MK BT OX GC MV AT LU KV

四、Playfair算法编程

这里我不想直接贴代码。想仔细说下编程的思路以及中间遇到的一些问题。因为刚开始百度参考别人的博客都是直接贴代码,没说思路,看代码又不大懂。搞得我都是自己编的代码。

流程图(重要)

我画的流程图网址https://www.processon.com/diagraming/5839ae8de4b086d1e7cba620

妈呀!流程图已经把我想说的大都说了~~尴尬~

如果加密做了,解密真的很简单的。接下来说下我遇到的几个问题,卡住挺久的~

问题及分析

 问题1. 一组字母是重复明文字母,则插入字母Z(我设的,你也可以设别的),如何实现??

我刚开始的做法是循环明文列表,依次找出第奇数(为什么不先找偶数?先找偶数之后就得去找下一个元素(奇数),怕下标越界)个元素,然后比较奇数前面一个元素(偶数)是否相同,相同则插入字母Z。然而问题来了?每次我插入一个Z,列表及下标就会变化,这样就得重新循环插入才行!

1     for i in range(len(list_clear_text)):
2         if(i % 2 == 1):   #列表中的第d奇数个
3             if(list_clear_text[i] == list_clear_text[i-1]):   #第奇数个与前一个(偶数)是否相同
4                 list_clear_text.insert(i, "Z")   #有重复明文字母则插入一个填充字母Z 并且退出循环
5                 break

然后我们用个while循环调用上面代码就可以了。接下来的问题是:如何退出while循环,即如何判断列表没有一组字母是重复的明文字母。这里我想了想,决定用一个count来计数,每一组明文字母不相同时,则count+1,当 count == int(len(list_clear_text) / 2)时便可退出循环!

 1 #处理一组字线是重复明文字母
 2 def deal_repeat(list_clear_text):
 3     count = 0    #计算列表中有多少组是不同的
 4     flag = False
 5     for i in range(len(list_clear_text)):
 6         if(i % 2 == 1):   #列表中的第d奇数个
 7             if(list_clear_text[i] == list_clear_text[i-1]):   #第奇数个与前一个(偶数)是否相同
 8                 list_clear_text.insert(i, "Z")   #有重复明文字母则插入一个填充字母Z 并且退出循环
 9                 break
10             if (list_clear_text[i] != list_clear_text[i - 1]):
11                 count += 1
12                 if count == int(len(list_clear_text) / 2):
13                     flag = True
14
15     return list_clear_text,flag   #返回的是元组 (list_clear_text, flag)

啪啪啪!问题解决!接下来说个解密时遇到的问题。

问题2:解密时先判断列表最后一个是否Z,是的话删除,接着问题来了,如何删除加密时在一组重复的明文中填充的字母Z???

我刚开始的做法是先判断(decryption_list[i]为第偶数个,若与decryption_list[i+2]相同,并且中间decryption_list[i+1] == "Z"等于Z,则删除中间的Z)

1     for i in range(len(decryption_list)):
2         if i % 2 == 0:
3             if i+2 < len(decryption_list) and 4                             decryption_list[i] == decryption_list[i+2] and decryption_list[i+1] == "Z":
5                 delete_list.pop(i+1)

为了方便看上面的判断,我贴下测试:

请输入明文:aabbbcccc
[‘a‘, ‘a‘, ‘b‘, ‘b‘, ‘b‘, ‘c‘, ‘c‘, ‘c‘, ‘c‘]
[‘a‘, ‘Z‘, ‘a‘, ‘b‘, ‘b‘, ‘Z‘, ‘b‘, ‘c‘, ‘c‘, ‘Z‘, ‘c‘, ‘Z‘, ‘c‘]
[‘a‘, ‘Z‘, ‘a‘, ‘b‘, ‘b‘, ‘Z‘, ‘b‘, ‘c‘, ‘c‘, ‘Z‘, ‘c‘, ‘Z‘, ‘c‘, ‘Z‘]      #最后添加字母Z

问题来了,和问题1一样,每删除一个Z,列表与下标也随之变化了啊!怎么办??像问题1那样循环删除?这样搞,我有几条命都不够用来打代码。有没有简单的?啪啪啪。灵光一现,我可以从后往前删除,这样就不怕列表下标变化了,用一个空列表来装我要删除元素的下标。

 1     delete_list = []
 2     for i in range(len(decryption_list)):
 3         if i % 2 == 0:          #第偶数个
 4             #不越界
 5             if i+2 < len(decryption_list) and  6                             decryption_list[i] == decryption_list[i+2] and decryption_list[i+1] == "Z":
 7                 delete_list.append(i+1)
 8                 #decryption_list.pop(i+1)
 9     delete_list.reverse()     #反序,从后往前删除,每次删完下标就不会再变化,我真是太聪明了!
10     for i in delete_list:
11         print(i)
12         decryption_list.pop(i)

问题3:我设定的是插入Z,当时我想的是如果一组重复的明文刚好是zz,那还能插入Z(我设定的)?以及如果明文列表最后一个刚好是z,那我还能在最后补充Z??

于是,测试如下:

 

通过测试,也没问题,因为解密时会把多余的Z删除。(看来我想多了~)

问题4: 好尴尬的BUG

加密时,不论时文abc, 还是abcz,加密后的密文均为BJDU,那惨了,那BJDU解密时,是abc?还是abcz??

Please input E for encryption or D for decryption:E
请输入明文(小写字母):ABC
[‘A‘, ‘B‘, ‘C‘]
[‘A‘, ‘B‘, ‘C‘]
[‘A‘, ‘B‘, ‘C‘, ‘Z‘]
加密成功!密文:BJDU
Please input E for encryption or D for decryption:D
请输入密文(大写字母/偶数):BJDU
解密成功!明文:ABC
Please input E for encryption or D for decryption:E
请输入明文(小写字母):abcz
[‘a‘, ‘b‘, ‘c‘, ‘z‘]
[‘a‘, ‘b‘, ‘c‘, ‘z‘]
[‘a‘, ‘b‘, ‘c‘, ‘z‘]
加密成功!密文:BJDU
Please input E for encryption or D for decryption:D
请输入密文(大写字母/偶数):BJDU
解密成功!明文:ABC
Please input E for encryption or D for decryption:

不管了,大家不必死钻这个BUG,如果有啥好办法可以与我交流下,我吃饭去了……

五、总结

  • 有半个月没用python了,列表操作有些竟然忘了。尴尬~
  • list.pop()删除指定下标的元素,默认删除最后一个元素
  • 列表的list.reverse()返回值是None
  • 方法return 1,2  其实是返回一个元组(1, 2)
  • print(int(7/2)) 输出3

 源代码

 

 测试用例

 

时间: 2024-10-06 04:09:56

信息安全-1:python之playfair密码算法详解[原创]的相关文章

密码算法详解——DES

0 DES简介 在20世纪60年代后期,IBM公司成立了一个由Horst Feistel负责的计算机密码学研究项目.1971年设计出算法LUCIFER后,该项目宣告结束.LUCIFER被卖给了伦敦的Lloyd公司,用在同样由IBM公司开发的现金发放系统上.LUCIFER是分组长度为64位.密钥长度为128位.具有Feistel结构的分组密码.因为LUCIFER非常成功,IBM决定开发一个适合于芯片实现的商业密码产品.这一次由Walter Tuchman和Carl Meyer牵头,参与者不仅有IB

密码算法详解——AES

0 AES简介 美国国家标准技术研究所在2001年发布了高级加密标准(AES).AES是一个对称分组密码算法,旨在取代DES成为广泛使用的标准. 根据使用的密码长度,AES最常见的有3种方案,用以适应不同的场景要求,分别是AES-128.AES-192和AES-256.本文主要对AES-128进行介绍,另外两种的思路基本一样,只是轮数会适当增加. 1 算法流程 AES加解密的流程图如下: AES加密过程涉及到4种操作:字节替代(SubBytes).行移位(ShiftRows).列混淆(MixCo

python 几个简单算法详解

一.冒泡排序 基本思想:它的思路很有特点循环,两两向后比较.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成. #冒泡排序 # def bubble_sort(li): # for i in range(len(li)-1): #走一趟,循环的次数 # for j in range(len(li)-i-1): #有序列为,len(li)-i,去掉有序不循环 # if li[j]>li[j+1

机器学习经典算法详解及Python实现---朴素贝叶斯分类及其在文本分类、垃圾邮件检测中的应用

摘要: 朴素贝叶斯分类是贝叶斯分类器的一种,贝叶斯分类算法是统计学的一种分类方法,利用概率统计知识进行分类,其分类原理就是利用贝叶斯公式根据某对象的先验概率计算出其后验概率(即该对象属于某一类的概率),然后选择具有最大后验概率的类作为该对象所属的类.总的来说:当样本特征个数较多或者特征之间相关性较大时,朴素贝叶斯分类效率比不上决策树模型:当各特征相关性较小时,朴素贝叶斯分类性能最为良好.另外朴素贝叶斯的计算过程类条件概率等计算彼此是独立的,因此特别适于分布式计算.本文详述了朴素贝叶斯分类的统计学

机器学习经典算法详解及Python实现--基于SMO的SVM分类器

原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector machine,简称SVM.通俗来讲,它是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,其学习策略便是间隔最大化,最终可转化为一个凸二次规划问题的求解. (一)理解SVM基本原理 1,SVM的本质--分类 给定一些数据点,它们分别属于两个不同的类,现在要找到一个线性分类器把这些

机器学习经典算法详解及Python实现--聚类及K均值、二分K-均值聚类算法

摘要 聚类是一种无监督的学习(无监督学习不依赖预先定义的类或带类标记的训练实例),它将相似的对象归到同一个簇中,它是观察式学习,而非示例式的学习,有点像全自动分类.说白了,聚类(clustering)是完全可以按字面意思来理解的--将相同.相似.相近.相关的对象实例聚成一类的过程.机器学习中常见的聚类算法包括 k-Means算法.期望最大化算法(Expectation Maximization,EM,参考"EM算法原理").谱聚类算法(参考机器学习算法复习-谱聚类)以及人工神经网络算法

机器学习经典算法详解及Python实现--CART分类决策树、回归树和模型树

摘要: Classification And Regression Tree(CART)是一种很重要的机器学习算法,既可以用于创建分类树(Classification Tree),也可以用于创建回归树(Regression Tree),本文介绍了CART用于离散标签分类决策和连续特征回归时的原理.决策树创建过程分析了信息混乱度度量Gini指数.连续和离散特征的特殊处理.连续和离散特征共存时函数的特殊处理和后剪枝:用于回归时则介绍了回归树和模型树的原理.适用场景和创建过程.个人认为,回归树和模型树

机器学习经典算法详解及Python实现--线性回归(Linear Regression)算法

(一)认识回归 回归是统计学中最有力的工具之一.机器学习监督学习算法分为分类算法和回归算法两种,其实就是根据类别标签分布类型为离散型.连续性而定义的.顾名思义,分类算法用于离散型分布预测,如前面讲过的KNN.决策树.朴素贝叶斯.adaboost.SVM.Logistic回归都是分类算法:回归算法用于连续型分布预测,针对的是数值型的样本,使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签. 回归的目的就是建立一个回归方程用来预测目

Python 生成账号密码算法

有个需求,需要伪造跟用户行为非常类似的账号密码,而且需要一个阀值控制伪造的数量. 在这需求上,还有一个就是需要控制生成的比率.跳出率不能过高或者太低. 对此就随手用python写了一个,bug不知道有木有,没有测,具体有兴趣可以去改改. #coding:utf-8 import random class create_data: global zimu_xx,zimu_dx,number,teshu # 生成26个英文字母,大小写 zimu_xx=[chr(i) for i in range(9