ADFGX密码

简介: ADFGX密码

ADFGX密码

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


A
D G F X
A x y z d e
D f g h i k
G l m n o p
F q r s t u
X v w c b z


  • 将密文的每个字符查表转为相应的ADGFX字符对,前面是横排,后面是纵列,如字符o查表为GF。
  • 再将刚刚查表后的字符串根据密钥如下排列(假设密钥是linux, 刚刚查表后得到的是FXDDXGDFFGFFGG):

l i n u x
F X D D X
G D F F X
F F G G
  • 再根据密钥字符的ascii码大小对上表的列按从小到大排列
i l n u x
X F D D X
D G F F X
F F F G

  • 最后按列将密文去除,如上表取出为: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_}")


目录
打赏
0
相关文章
C/C++编程题之简单密码
密码是我们生活中非常重要的东东,我们的那么一点不能说的秘密就全靠它了。哇哈哈. 接下来渊子要在密码之上再加一套密码,虽然简单但也安全。
密码
============================================       请下载12小时内删除,不得用于商业用途 ============================================     密码:  ok
471 0
HDOJ 2043 密码
Problem Description 网上流传一句话:”常在网上飘啊,哪能不挨刀啊~”。其实要想能安安心心地上网其实也不难,学点安全知识就可以。 首先,我们就要设置一个安全的密码。
1082 0
Vigen&#232;re密码
来源  NOIP2012复赛 提高组 第一题 描述 16世纪法国外交家Blaise de Vigenère设计了一种多表密码加密算法——Vigenère密码。Vigenère密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为南军所广泛使用。
1162 0
如何取安全的密码?
如何取安全的密码?
103 0