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_}")