密码学—Playfair加密算法 python实现

本文详细介绍了Playfair密码的加密和解密算法实现,包括创建密钥矩阵、获取字符位置、加解密核心逻辑等步骤。代码不涉及加密原理的解释,但能帮助读者理解算法操作。请注意,解密时末尾的'X'可能需要语义分析来确定是否删除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇文章主要介绍代码实现,而不介绍具体加密原理,具体原理读者可以自行百度。

# Playfair密码

#(创建密钥矩阵的算法小部分参考了其他人的做法,具体加解密核心代码则为原创)
# 字母表
letter_list = 'ABCDEFGHIKLMNOPQRSTUVWXYZ'

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

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

    for ch in letter_list:  # 根据密钥获取新组合的字母表
        if ch not in key:
            key += ch
    # 密码表
    keys = [[i for j in range(5)] for i in range(5)]
    for i in range(len(key)):  # 将新的字母表里的字母逐个填入密码表中,组成5*5的矩阵
        keys[i // 5][i % 5] = key[i]  # j用来定位字母表的行
    return keys

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

def get_ctext(ch1, ch2, keys):
    index1 = get_matrix_index(ch1, keys)
    index2 = get_matrix_index(ch2, keys)
    r1, c1, r2, c2 = index1[0], index1[1], index2[0], index2[1]
    if r1 == r2:
        ch1 = keys[r1][(c1+1) % 5]
        ch2 = keys[r2][(c2+1) % 5]
    elif c1 == c2:
        ch1 = keys[(r1+1) % 5][c1]
        ch2 = keys[(r2+1) % 5][c2]
    else:
        ch1 = keys[r1][c2]
        ch2 = keys[r2][c1]
    text = ''
    text += ch1
    text += ch2
    return text

def get_ptext(ch1, ch2, keys):
    index1 = get_matrix_index(ch1, keys)
    index2 = get_matrix_index(ch2, keys)
    r1, c1, r2, c2 = index1[0], index1[1], index2[0], index2[1]
    if r1 == r2:
        ch1 = keys[r1][(c1-1) % 5]
        ch2 = keys[r2][(c2-1) % 5]
    elif c1 == c2:
        ch1 = keys[(r1-1) % 5][c1]
        ch2 = keys[(r2-1) % 5][c2]
    else:
        ch1 = keys[r1][c2]
        ch2 = keys[r2][c1]
    text = ''
    text += ch1
    text += ch2
    return text

def playfair_encode(plaintext, key):
    plaintext = plaintext.replace(" ", "")
    plaintext = plaintext.upper()
    plaintext = plaintext.replace("J", "I")
    plaintext = list(plaintext)
    plaintext.append('#')
    plaintext.append('#')

    keys = create_matrix(key)
    ciphertext = ''
    i = 0
    while plaintext[i] != '#':
        if plaintext[i] == plaintext[i+1]:
            plaintext.insert(i+1, 'X')
        if plaintext[i+1] == '#':
            plaintext[i+1] = 'X'
        ciphertext += get_ctext(plaintext[i], plaintext[i+1], keys)
        i += 2
    return ciphertext

def playfair_decode(ciphertext, key):
    keys = create_matrix(key)
    i = 0
    plaintext = ''
    while i < len(ciphertext):
        plaintext += get_ptext(ciphertext[i], ciphertext[i+1], keys)
        i += 2
    _plaintext = ''
    _plaintext += plaintext[0]
    for i in range(1, len(plaintext)-1):
        if plaintext[i] != 'X':
            _plaintext += plaintext[i]
        elif plaintext[i] == 'X':
            if plaintext[i-1] != plaintext[i+1]:
                _plaintext += plaintext[i]
    _plaintext += plaintext[-1]
    _plaintext = _plaintext.lower()
    return _plaintext


# plaintext = 'balloon'
# key = 'monarchy'
plaintext = input('明文:')
key = input('密钥:')
ciphertext = playfair_encode(plaintext, key)
print('加密后的密文:' + ciphertext)
plaintext = playfair_decode(ciphertext, key)
print('解密后的明文:' + plaintext)

       另外解密算法还有一个地方需要注意:因为加密算法会在明文末尾凑不够两个字母时加‘X’,然而解密时无法确认末尾的‘X’是明文本身拥有的还是加密算法添加的,所以编写的解密算法并没有设计将末尾的‘X’删去的功能,而是将这一步放入语义分析阶段。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值