# write by 2021/7/19
# ADFGVX密码, 是ADFGVX的加强版,可以加密a-z,0-9的字符串
import re
INDEX_DIC = "ADFGVX"
def judge_table(table):
if len(table) != 36:
print("密码表出问题", len(table))
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_adfgvx(string, table, key):
if not judge_table(table):
return -1
ciphertext = ""
ciphertext_temp = ""
for i in string:
index = table.index(i)
ciphertext_temp += INDEX_DIC[index // 6] + INDEX_DIC[index % 6]
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_adfgvx(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])*6 + int(i[1])]
# print(plaintext_temp)
return plaintext
if __name__ == '__main__':
table_ = "abcdefghijklmnopqrstuvwxyz0123456789"
key_ = "china"
ciphertext_ = encrypt_adfgvx("linux", table_, key_)
plaintext_ = decrypt_adfgvx(ciphertext_, table_, key_)
print(f"{plaintext_}: {ciphertext_}")