仿射密码为单表加密的一种,字母系统中所有字母都藉一简单数学方程加密,对应至数值,或转回字母。
加密:
E(x) = (ax + b) (mod m)
,其中 a与b互质,m是编码系统中字母的个数(通常都是26)。
解密:
D(x) = a^{-1} (x - b) (mod m)
,其中 a^{-1} 是 a 在Z_{m}群(此处为26)的乘法逆元。
# 创建字母表
def creatLetterList():
letterList = []
for i in range(ord("a"), ord("z") + 1):
letterList.append(chr(i))
return letterList
# 判断互质
def judgeCoPrime(a, b):
# 求最大公因数
def maxCommonFactor(m, n):
result = 0
while m % n > 0:
result = m % n
m = n
n = result
return result
if maxCommonFactor(a, b) == 1:
return True
return False
# 求逆元
def getInverse(a, b):
# 扩展的欧几里得
def extGcd(a_, b_, arr):
if b_ == 0:
arr[0] = 1
arr[1] = 0
return a_
g = extGcd(b_, a_ % b_, arr)
t = arr[0]
arr[0] = arr[1]
arr[1] = t - int(a_ / b_) * arr[1]
return g
# 求a模b的乘法逆x
arr = [0,1,]
gcd = extGcd(a, b, arr)
if gcd == 1:
return (arr[0] % b + b) % b
else:
return -1
# 加密
def encrypt(massage, keyOne, keyTwo):
massageList = [] # 存储明文字母转换的对应数字
cipherTextList = [] # 密文列表
letterList = creatLetterList() # 字母列表
for i in massage:
massageList.append(letterList.index(i))
for i in massageList:
cipherTextList.append((keyOne * i + keyTwo) % 26)
return cipherTextList
# 解密
def decrypt(cipherTextList, keyOne, keyTwo):
plainTextList = []
letterList = creatLetterList()
# 求keyOne对于26的逆元
inverse_keyOne = getInverse(keyOne, 26)
for i in cipherTextList:
plainTextList.append((inverse_keyOne * (i - keyTwo)) % 26)
for i in range(len(plainTextList)):
plainTextList[i] = letterList[plainTextList[i]]
# 将列表整合为字符串
plianText = "".join(plainTextList)
return plianText
# 输入并创建密钥
def creatKey():
while True:
keyOne = int(input("输入Key1(与26互质):"))
if not judgeCoPrime(keyOne, 26):
continue
keyTwo = int(input("输入Key2:"))
break
# 创建keyOne的逆元
inverse_keyOne = getInverse(keyOne, 26)
return keyOne, keyTwo, inverse_keyOne
if __name__ == "__main__":
while True:
print("——————仿射密码——————")
choice = input("1、加密 2、解密\n请选择:")
if choice == "1":
keyOne, keyTwo, inverse_keyOne = creatKey()
print("创建密钥成功: " %(keyOne, keyTwo, inverse_keyOne))
massage = input("输入明文:")
cipherTextList = encrypt(massage, keyOne, keyTwo)
print("加密结果:", cipherTextList)
elif choice == "2":
cipherTextList = list(map(int, list(input("输入密文序列:").split(","))))
keyOne, keyTwo, inverse_keyOne = creatKey()
plainText = decrypt(cipherTextList, keyOne, keyTwo)
print("解密结果:", plainText)
else:
continue
输入key1:17
输入key2:5
输入明文:abcdefg
产生的逆元:23
产生的密文:5, 22, 13, 4, 21, 12, 3
输入密文:5, 22, 13, 4, 21, 12, 3
输入key1:17
输入key2:5