Jump to content
  • Hello visitors, welcome to the Hacker World Forum!

    Red Team 1949  (formerly CHT Attack and Defense Team) In this rapidly changing Internet era, we maintain our original intention and create the best community to jointly exchange network technologies. You can obtain hacker attack and defense skills and knowledge in the forum, or you can join our Telegram communication group to discuss and communicate in real time. All kinds of advertisements are prohibited in the forum. Please register as a registered user to check our usage and privacy policy. Thank you for your cooperation.

    TheHackerWorld Official

密码学实验2 playfair密码的实现

 Share


Recommended Posts

  • 密码学实验2 playfair密码的实现

    这不是有手就行,一些刁钻的细节还没有研究,这里先只实现一般的加解密

    开始之前,我想说,有网站不香么playfair在线加解密.

    结束
    在这里插入图片描述

    一、准备工作

    首先playfair,第一次遇到在水古典密码的时候(加解密原理下面也有,具体的细节建议百度),与一般的多表加密和单表加密不同的是,它好像不能被词频,然后用类似多表替代的破解方案去的话,好像也不行,因为没有密钥填充的过程,嘎嘎嘎嘎
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    果然I和J也是一个攻击点

    好了,言归正传

    首先准备了两个函数,用来转换字母表和找到行列坐标

    def tableau_used(table):
        # 注意二维数组的初始化方式
        lists = [[' ' for _ in range(5)] for _ in range(5)]
        for i in range(len(table)):
            lists[i//5][i % 5] = table[i]
        return lists
    
    
    def find_xy(target, lists):
        for i in range(5):
            for j in range(5):
                if lists[i][j] == target:
                    return i, j

    二、加密

    大致的流程可参考度娘
    在这里插入图片描述
    遇到的一些问题,比如numpy库的二维数组里str和别的一般的str类型不同,可能会出错,还有从网上抄来的正则表达式的库re的使用,将字符串拆分成两个,其他都没什么吧

    def playfair_encode(plaintext, table):
        lists = tableau_used(table)
        # 密文处理,多出来或者重复的加X
        tmp_text = plaintext
        for i in ascii_uppercase:
            if i * 2 in tmp_text:
                tmp_text = tmp_text.replace(i+i, i+'X'+i)
        if len(tmp_text) % 2:
            tmp_text += 'X'
        tmp_text = re.sub(r"(?<=\w)(?=(?:\w\w)+$)", " ", tmp_text).split()
    
        ciphertext = ''
        # 加密三步走
        for ii in tmp_text:
            x1 = find_xy(ii[0], lists)[0]
            y1 = find_xy(ii[0], lists)[1]
            x2 = find_xy(ii[1], lists)[0]
            y2 = find_xy(ii[1], lists)[1]
            tmp_item = ''
            # 同一行
            if y1 == y2:
                tmp_item = lists[(x1+1) % 5][y1] + lists[(x2+1) % 5][y2]
            # 同一列
            elif x1 == x2:
                tmp_item = lists[x1][(y1 + 1) % 5] + lists[x2][(y2 + 1) % 5]
            # 矩形,规定横向替换
            else:
                tmp_item = lists[x1][y2] + lists[x2][y1]
            ciphertext += tmp_item
        return ciphertext

    三、解密

    解密也主要参考度娘
    在这里插入图片描述
    但其实就想必加密而言,改一下符号就好,而且没有加密繁琐

    def playfair_decode(ciphertext, table):
        lists = tableau_used(table)
        tmp_text = ciphertext
        tmp_text = re.sub(r"(?<=\w)(?=(?:\w\w)+$)", " ", tmp_text).split()
    
        ciphertext = ''
        # 加密三步走
        for ii in tmp_text:
            x1 = find_xy(ii[0], lists)[0]
            y1 = find_xy(ii[0], lists)[1]
            x2 = find_xy(ii[1], lists)[0]
            y2 = find_xy(ii[1], lists)[1]
            tmp_item = ''
            # 同一行
            if y1 == y2:
                tmp_item = lists[(x1 - 1) % 5][y1] + lists[(x2 - 1) % 5][y2]
            # 同一列
            elif x1 == x2:
                tmp_item = lists[x1][(y1 - 1) % 5] + lists[x2][(y2 - 1) % 5]
            # 矩形,规定横向替换
            else:
                tmp_item = lists[x1][y2] + lists[x2][y1]
            ciphertext += tmp_item
        return ciphertext

    四、测试

    字母表的生成放在测试这部分了

    # 构造加密解密使用的字母表
    table = key
    for i in alphabet:
        if i in table:
            continue
        table += i
    assert len(table) == 25
    j = 0
    print("得到的字母表如下:")
    for i in table:
        j += 1
        if i == 'I':
            print("I(J)", end='')
        else:
            print(i, end='\t')
        if j >= 5:
            print()
            j = 0
    

    这里我是规定用有J的地方用I来代替

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time : 2021/4/23 14:31
    # @Author : Will
    # @File : t3xt.py
    # @Software: PyCharm
    from sage import playfair_decode, playfair_encode, tableau_used
    from string import ascii_uppercase
    import sys
    # 将I和J视为同一个字母,这里把出现J的地方都当成I
    alphabet = ascii_uppercase.replace('J', '')
    
    print("请输入密钥:", end='')
    tmp_key = input().upper()
    tmp_key = tmp_key.replace('J', 'I')
    
    # 去重去空格
    tmp_key = "".join(tmp_key.split())
    key = ''
    for i in tmp_key:
        if i in key:
            continue
        key += i
    print(key)
    
    # 构造加密解密使用的字母表
    table = key
    for i in alphabet:
        if i in table:
            continue
        table += i
    assert len(table) == 25
    j = 0
    print("得到的字母表如下:")
    for i in table:
        j += 1
        if i == 'I':
            print("I(J)", end='')
        else:
            print(i, end='\t')
        if j >= 5:
            print()
            j = 0
    
    print('*****************')
    print("* 1.加密         *")
    print("* 2.解密         *")
    print("* 3.退出         *")
    print('*****************')
    print("请输入你的选择:", end='')
    tip = input()
    while 1:
        if tip == '1':
            print("请输入你要加密的明文:")
            plaintext = (''.join(input().split())).upper().replace('J', 'I')
            # 加密
            ciphertext = playfair_encode(plaintext, table)
            print("加密的结果是:{0}".format(ciphertext.upper()))
            break
        elif tip == '2':
            print("请输入你要解密的密文:")
            ciphertext = input().upper()
            # 解密
            plaintext = playfair_decode(ciphertext, table)
            if 'XX' in plaintext:
                print("WOW, you are so lucky! There are XX in your text.")
                continue
            if len(ciphertext) % 2 != 0:
                print("WOW, you make me very confused")
                continue
            print("解密的结果是:{0}".format(plaintext.lower()))
            break
        elif tip == '3':
            print("师傅再见")
            break
        else:
            print("我不想讨论这些问题")
            continue

    上面两个函数我单独拎出来,打算自己实现一个sage常见的加解密库

    五、运行结果

    在这里插入图片描述
    在这里插入图片描述
    应该是对的

    最后当然至于一些细节,能实现最好了(比如特殊字符的直接保留,还有结果报不保留原来的空格还有一些处理不了的特殊情况,I和J的问题等),但是凯撒本来也不支持大小写的,对伐

Link to post
Link to comment
Share on other sites

 Share

discussion group

discussion group

    You don't have permission to chat.
    • Recently Browsing   0 members

      • No registered users viewing this page.
    ×
    ×
    • Create New...