#########################Playfair密码#########################  

#约定1:若明文字母数量为奇数,在明文末尾添加一个'Z'
#约定2:'I'作为'J'来处理  

#字母表
letter_list='ABCDEFGHJKLMNOPQRSTUVWXYZ'  

#密码表
T_letter=['','','','','']  

#根据密钥建立密码表
def Create_Matrix(key):
  key=Remove_Duplicates(key)  #移除密钥中的重复字母
  key=key.replace(' ','') #去除密钥中的空格  

  for ch in letter_list:  #根据密钥获取新组合的字母表
    if ch not in key:
      key+=ch  

  j=0
  for i in range(len(key)): #将新的字母表里的字母逐个填入密码表中,组成5*5的矩阵
    T_letter[j]+=key[i]     #j用来定位字母表的行
    if 0==(i+1)%5:
      j+=1  

#移除字符串中重复的字母
def Remove_Duplicates(key):
  key=key.upper() #转成大写字母组成的字符串
  _key=''
  for ch in key:
    if ch=='I':
      ch='J'
    if ch in _key:
      continue
    else:
      _key+=ch
  return _key  

#获取字符在密码表中的位置
def Get_MatrixIndex(ch):
  for i in range(len(T_letter)):
    for j in range(len(T_letter)):
      if ch==T_letter[i][j]:
        return i,j #i为行,j为列  

#加密
def Encrypt(plaintext,T_letter):
  ciphertext=''  

  if len(plaintext) % 2 !=0:  #如果新的明文长度为奇数,在其末尾添上'Z'
    plaintext+='Z'  

  i=0
  while i<len(plaintext): #对明文进行遍历
    if True==plaintext[i].isalpha():  #如果是明文是字母的话,
      j=i+1                           #则开始对该字母之后的明文进行遍历,
      while j<len(plaintext):         #直到遍历到字母,进行加密
        if True==plaintext[j].isalpha():
          if 'I'==plaintext[i].upper():             #
            x=Get_MatrixIndex('J')                  #
          else:                                     #
            x=Get_MatrixIndex(plaintext[i].upper()) #对字符在密码表中的坐标
          if 'I'==plaintext[j].upper():             #进行定位,同时将'I'作为
              y=Get_MatrixIndex('J')                #'J'来处理
          else:                                     #
            y=Get_MatrixIndex(plaintext[j].upper()) #  

          if x[0]==y[0]:    #如果在同一行
            ciphertext+=T_letter[x[0]][(x[1]+1)%5]+T_letter[y[0]][(y[1]+1)%5]
          elif x[1]==y[1]:  #如果在同一列
            ciphertext+=T_letter[(x[1]+1)%5][x[0]]+T_letter[(y[1]+1)%5][y[0]]
          else:             #如果不同行不同列
            ciphertext+=T_letter[x[0]][y[1]]+T_letter[y[0]][x[1]]
          break;  #每组明文对加密完成后,结束本次对明文的遍历
        j+=1
      i=j+1  #每次对明文的遍历是从加密过后的明文的后一个明文开始的,结束本次循环
      continue
    else:
      ciphertext+=plaintext[i]  #如果明文不是字母,直接加到密文上
    i+=1  

  return ciphertext  

#解密
def Decrypt(ciphertext,T_letter):
  plaintext=''
  if len(ciphertext) % 2 !=0:  #如果新的密文长度为奇数,在其末尾添上'Z'
    ciphertext+='Z'  

  i=0
  while i<len(ciphertext): #对密文进行遍历
    if True==ciphertext[i].isalpha():  #如果是密文是字母的话,
      j=i+1                            #则开始对该字母之后的密文进行遍历,
      while j<len(ciphertext):         #直到遍历到字母,进行解密
        if True==ciphertext[j].isalpha():
          if 'I'==ciphertext[i].upper():              #
            x=Get_MatrixIndex('J')                    #
          else:                                       #
            x=Get_MatrixIndex(ciphertext[i].upper())  #对字符在密码表中的坐标
          if 'I'==ciphertext[j].upper():              #进行定位,同时将'I'作为
              y=Get_MatrixIndex('J')                  #'J'来处理
          else:                                       #
            y=Get_MatrixIndex(ciphertext[j].upper())  #  

          if x[0]==y[0]:    #如果在同一行
            plaintext+=T_letter[x[0]][(x[1]-1)%5]+T_letter[y[0]][(y[1]-1)%5]
          elif x[1]==y[1]:  #如果在同一列
            plaintext+=T_letter[(x[1]-1)%5][x[0]]+T_letter[(y[1]-1)%5][y[0]]
          else:             #如果不同行不同列
            plaintext+=T_letter[x[0]][y[1]]+T_letter[y[0]][x[1]]
          break;  #每组密文对解密完成后,结束本次对密文的遍历
        j+=1
      i=j+1  #每次对密文的遍历是从解密过后的密文的后一个密文开始的,结束本次循环
      continue
    else:
      plaintext+=ciphertext[i]  #如果密文不是字母,直接加到明文上
    i+=1  

  return plaintext  

#主函数
if __name__=='__main__':
  print("加密请按D,解密请按E:")
  user_input=input();
  while(user_input!='D' and user_input!='E'):#输入合法性检测
    print("输入有误!请重新输入:")
    user_input=input()  

  print('请输入密钥,密钥由英文字母组成:')
  key=input()  

  Create_Matrix(key)  #建立密码表  

  if user_input=='D': #加密
    print('请输入明文:')
    plaintext=input()
    print("密文为:\n%s" % Encrypt(plaintext,T_letter))
  else:               #解密
    print('请输入密文:')
    ciphertext=input()
    print('明文为:\n%s' % Decrypt(ciphertext,T_letter))  

python playfair的更多相关文章

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

    转发注明出处: http://www.cnblogs.com/0zcl/p/6105825.html 一.基本概念 古典密码是基于字符替换的密码.加密技术有:Caesar(恺撒)密码.Vigenere ...

  2. Playfair加密

    前面讲的不管是单码加密还是多码加密都属于单图加密,什么是单图加密和多图加密呢,简单来说单图加密就是一个字母加密一个字母,而多图加密就是一个字符组加密一个字符组.比如双图加密就是两个字母加密两个字母,这 ...

  3. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  4. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  5. Python 小而美的函数

    python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况   any any(iterable) ...

  6. JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议

    软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...

  7. 可爱的豆子——使用Beans思想让Python代码更易维护

    title: 可爱的豆子--使用Beans思想让Python代码更易维护 toc: false comments: true date: 2016-06-19 21:43:33 tags: [Pyth ...

  8. 使用Python保存屏幕截图(不使用PIL)

    起因 在极客学院讲授<使用Python编写远程控制程序>的课程中,涉及到查看被控制电脑屏幕截图的功能. 如果使用PIL,这个需求只需要三行代码: from PIL import Image ...

  9. Python编码记录

    字节流和字符串 当使用Python定义一个字符串时,实际会存储一个字节串: "abc"--[97][98][99] python2.x默认会把所有的字符串当做ASCII码来对待,但 ...

随机推荐

  1. [js开源组件开发]图片放大镜

    图片放大镜 一般情况下,手机由于屏幕太小,会有图片上看不清的问题,所以我就做了一个放大镜的js效果,支持pc和移动端.它的原理是利用的backgroundsize来实现的,所以你的浏览器首先要支持这个 ...

  2. Android WebView 获取网页的标题

    final TextView txtTitle = (TextView) findViewById(R.id.txtTitle); final WebView webView = (WebView)f ...

  3. 实战3--应用EL表达式判断用户登录信息

    1.判断用户名是否为空,空则显示提示信息 (1)编写index.jsp页面 <%@ page language="java" contentType="text/h ...

  4. E/AndroidRuntime(1636): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.***.app.wx.MainActivity} : android.view.InflateException: Binary XML file line #51 :

    类中加载的xml中,所自定义组件的包名错误(xml中51行错误:自定义组件包名写错了).

  5. 【读书笔记】iOS-开发技巧-UILabel内容模糊的原因

    在非Retina的iPad mini的屏幕上,一个UILabel的frame的origin值如果有小数位数(例如,0.5),就会造成显示模糊.所以最好用整数值的origin坐标. 参考资料: < ...

  6. C语言中的字符和字符串

    C语言在中常常出现字符和字符串,而一串字符或者字符串其实就是数组 字符数组的定义 char arr[]={'h','e','l','l','o','\0'}; 而定义字符串: char arr1[]= ...

  7. iOS-多线程之NSOperation

    前言 这篇文章主要讲NSOperation的使用. What 使用NSOperation和NSOperationQueue进行多线程开发类似于线程池,只要将一个NSOperation(实际开发中需要使 ...

  8. win7操作技巧

    Q : 打开文件夹默认最大化A :随便打开一个文件夹 鼠标移动到左上角 然后点击鼠标左键 选择“最大化” 后关闭 之后每次打开就是最大化了

  9. 21分钟 MySQL 入门教程

    目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数据类型 五.使用MySQL数据库 ...

  10. 为什么Erlang比C慢那么多倍?

    Erlang 一直以慢“著称”,本文就来看看 Erlang 慢在什么地方,为什么比实现同样功能的 C 语言程序慢那么多倍.Erlang 作为一种虚拟机解释的语言,慢是当然的.不过本文从细节上分析为什么 ...