ADFGX密码

本文介绍了ADFGX密码的加密和解密过程,这是一种使用5x5密码表和密钥进行字母替换的加密方法。通过示例详细展示了如何根据给定的密码表和密钥对明文进行加密和解密,同时提供了Python代码实现。该密码体制的特点是密文长度为明文的两倍,仅包含ADFGX五个字符。

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

ADFGX密码

  • 加密对象:小写字母
  • 原理:
    • 改密码在加密和解密时需要输入两个东西,一个密码表,一个密钥,密码表时5x5的polybius表格,里面的字符是a-z(i和j看作同一个)打乱顺序的,出去j刚好填满25个格子。其中的横纵坐标是由ADFGX表示的,如密码表为:“xyzdefghijklmnopqrstuvwcba”,如下:

      ADGFX
      Axyzde
      Dfghik
      Glmnop
      Fqrstu
      Xvwcbz
    • 将密文的每个字符查表转为相应的ADGFX字符对,前面是横排,后面是纵列,如字符o查表为GF。

    • 再将刚刚查表后的字符串根据密钥如下排列(假设密钥是linux, 刚刚查表后得到的是FXDDXGDFFGFFGG):

      linux
      FXDDX
      GDFFX
      FFGG
    • 再根据密钥字符的ascii码大小对上表的列按从小到大排列

      ilnux
      XFDDX
      DGFFX
      FFFG
    • 最后按列将密文去除,如上表取出为:XDFFGFDFFDFGXX

  • 特点:
    • 密文长度是明文的两倍,即密文是偶数
    • 密文字符仅有ADFGX这几个字符
  • 代码
    # write by 2021/7/19
    # ADFGX密码
    
    import re
    
    INDEX_DIC = "ADFGX"
    
    
    def judge_table(table):
        if len(table) != 25:
            return 0
        return 1
    
    
    def sort_key(key):
        key_len = len(key)
        key_lis = re.findall(".", key)
        index_lis = [i for i in range(key_len)]
        # print(key_lis)
        # print(index_lis)
        # 冒泡法
        for i in range(key_len):
            for j in range(key_len-i-1):
                if key_lis[j] > key_lis[j+1]:
                    key_lis[j], key_lis[j+1] = key_lis[j+1], key_lis[j]
                    index_lis[j], index_lis[j+1] = index_lis[j+1], index_lis[j]
        # print(key_lis)
        # print(index_lis)
        return index_lis
    
    
    def encrypt_adfgx(string, table, key):
        if not judge_table(table):
            return -1
        ciphertext = ""
        ciphertext_temp = ""
        for i in string.replace("j", "i"):
            index = table.index(i)
            ciphertext_temp += INDEX_DIC[index // 5] + INDEX_DIC[index % 5]
        ciphertext_lis = re.findall(".{1,"+str(len(key))+"}", ciphertext_temp)
        # print("ciphertext_lis", ciphertext_lis)
        sort_index = sort_key(key)
        for index in sort_index:
            for j in ciphertext_lis:
                try:
                    ciphertext += j[index]
                except:
                    pass
        # print(ciphertext_temp)
        return ciphertext
    
    
    def decrypt_adfgx(string, table, key):
        key_len = len(key)
        string_len = len(string)
        if not judge_table(table):
            return -1
        if string_len % 2 != 0:
            return -1
        plaintext = ""
        plaintext_temp = ""
        plaintext_lis = []
    
        # 一列最小个数
        min_lin = string_len // key_len
        # 有多少最大个数的列
        max_col = string_len % key_len
        # print(f"m={m}, n={n}")
        index = 0
        # 分组
        sort_index = sort_key(key)
        for i in sort_index:
            if i < max_col:
                plaintext_lis.append(string[index:index+min_lin+1])
                index += min_lin+1
            else:
                plaintext_lis.append(string[index:index+min_lin])
                index += min_lin
        # 还原列顺序
        for i in range(key_len-1):
            for j in range(key_len-i-1):
                if sort_index[j] > sort_index[j+1]:
                    sort_index[j], sort_index[j+1] = sort_index[j+1], sort_index[j]
                    plaintext_lis[j], plaintext_lis[j+1] = plaintext_lis[j+1], plaintext_lis[j]
        # 合成字符串,并转为横纵坐标
        for i in range(min_lin+1):
            for j in plaintext_lis:
                try:
                    plaintext_temp += str(INDEX_DIC.index(j[i]))
                except:
                    pass
        # 查表
        plaintext_num_lis = re.findall(".{2}", plaintext_temp)
        for i in plaintext_num_lis:
            plaintext += table[int(i[0])*5 + int(i[1])]
        # print(plaintext_temp)
        return plaintext
    
    
    if __name__ == '__main__':
        table_ = "phqgmeaynofdxkrcvszwbutil"
        key_ = "china"
        ciphertext_ = encrypt_adfgx("njntysecu", table_, key_)
        plaintext_ = decrypt_adfgx(ciphertext_, table_, key_)
        print(f"{plaintext_}: {ciphertext_}")
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值