跳转到帖子

游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

TheHackerWorld官方

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

精选回复

发布于
  • 密码学实验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的问题等),但是凯撒本来也不支持大小写的,对伐

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。