仿射密码(Affine Cipher)是一种古老的单字母替换密码,属于经典密码学范畴。
加密 #
$$ E(x) = (a\cdot x + b) \mod{m} $$
- E(x)是加密后的字符的数值
- x是明文字符的数值,通常是字母表的位置(A=0,B=1,…,Z=25)
- a和b是密钥,而且a必须和m互质(在字母表中,通常m=26)
- m是字符集的大小(对于英文字母,m=26)
加密步骤:
- 将明文字符转换为数字。
- 使用E(x)公式进行加密。
- 将加密后的数字转换回字符。
解密 #
仿射密码的解密过程可以用以下公式表示: $$ D(y) = a^-1\cdot(y-b)\mod{m} $$
- D(y)是解密后的字符的数值
- y是加密后的字符串的数值
- $a^-1$是a的模逆元素,满足$a\cdot a^-1 \equiv 1\mod{m}$
- b是加密时使用的密钥
- m是字符集的大小
解密步骤:
- 计算a的模逆元素$a^-1$
- 将加密字符转换为数字。
- 使用D(y)进行解密。
- 将解密后的数字转换回字符。
加密解密Py脚本(26个字母) #
#Affine Cipher (仿射密码)
from gmpy2 import invert
Htable="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Ltable="abcdefghijklmnopqrstuvwxyz"
#求最大公约数(GCD,Greatest Common Divisor)
#辗转相除法
def gcd(a,b):
#b=0时,整除了,即最大公约数
while b:
a,b=b,a%b #b是余数,赋值给a,下一轮继续求余数
return a
#判断a是否和b互质
def are_coprime(a,b):
#最大公约数是1,则互质
return gcd(a,b)==1
def affine_encrypt(text,a,b,m):
enc_text=""
if are_coprime(a,m):
for i in text:
if 'A'<=i<='Z':
enc_text+=Htable[(a*(Htable.index(i))+b)%m]
elif 'a'<=i<='z':
enc_text+=Ltable[(a*(Ltable.index(i))+b)%m]
else:
enc_text+=i
return enc_text
else:
print("a和m不互质,无法加密")
def affine_decrypt(text,a,b,m):
dec_text=""
if are_coprime(a,m):
#好吧...其实扩展欧几里得和求模逆元还没学明白,就直接用了gmpy2的
a_inv = invert(a, m)
print(a_inv)
for i in text:
if 'A'<=i<='Z':
dec_text+=Htable[(a_inv * (Htable.index(i)-b) ) %m]
elif 'a'<=i<='z':
dec_text+=Ltable[(a_inv * (Ltable.index(i)-b) ) %m]
else:
dec_text+=i
return dec_text
else:
print("a和m不互质,无法解密")
c = affine_encrypt("flag{aff1n3_encrp4y}",3,4,26)
print(f"密文:{c}")
m = affine_decrypt(c,3,4,26)
print(f"明文:{m}")