# -*- coding: UTF-8 -*-import math
"""仿射密碼加密解密模塊@author WQ@time 2020/11/18
"""classAffine():"""仿射密碼Encrypt:加密方法Decrypt:解密方法letters:字母數(shù)字對(duì)應(yīng)字典"""def__init__(self):self.ciphertext=''#加密后的密文self.plaintext=''#解密后的明文self.reverse=0#秘鑰a的逆元self.list_keya=[3,5,7,9,11,15,17,19,21,23,25]#秘鑰a可能取值self.letters ={'a':0,'b':1,'c':2,'d':3,'e':4,'f':5,'g':6,'h':7,'i':8,'j':9,'k':10,'l':11,'m':12,'n':13,'o':14,'p':15,'q':16,'r':17,'s':18,'t':19,'u':20,'v':21,'w':22,'x':23,'y':24,'z':25}defgcd(self,a,b=26):if(a<b):return self.gcd(b,a)while(a%b!=0):temp = bb = a%ba = tempreturn b defEncrypt(self,a=0,b=0,input=""):"""對(duì)輸入的字符串進(jìn)行加密加密算法:c=Ea,b(m)=am+b(mod26) m是單個(gè)明文字母args={a,b:秘鑰input:用于加密的明文} """if(self.gcd(a)!=1):print("秘鑰a錯(cuò)誤,應(yīng)與26互質(zhì),請(qǐng)重輸!")exit(0)if(b>=26):print("秘鑰b錯(cuò)誤[0~26],請(qǐng)重輸!")exit(0)input=input.lower()digitals=[]#加密轉(zhuǎn)化成密文對(duì)應(yīng)數(shù)字for i ininput:for j in self.letters:if(i==j):d=(a*self.letters[i]+b)%26digitals.append(d)#將對(duì)應(yīng)數(shù)字轉(zhuǎn)化對(duì)應(yīng)密文字母for i in digitals:for j in self.letters:if(i==self.letters[j]):self.ciphertext=self.ciphertext+j defDecrypt(self, a, b,input=""):"""對(duì)輸入的字符串進(jìn)行解密解密算法:m=Da,b(m)=a(-1)(c-b)(mod26) c是單個(gè)密文字母args={a(-1):秘鑰a的逆元b:秘鑰input:用于解密的秘文} """if(self.gcd(a)!=1):print("秘鑰a錯(cuò)誤,應(yīng)與26互質(zhì),請(qǐng)重輸!")exit(0)if(b>=26):print("秘鑰b錯(cuò)誤[0~26],請(qǐng)重輸!")exit(0)digitals=[]self.reverse=self.Inverse(a)#求逆元for i ininput:#解密 密文轉(zhuǎn)化成對(duì)應(yīng)數(shù)字for j in self.letters:if(i==j):digitals.append(self.letters[j])#解密for i in digitals:t=(self.reverse*(i-b))%26for j in self.letters:if(t==self.letters[j]):self.plaintext=self.plaintext+jdefBruteForce(self,input=''):#暴力破解仿射密碼digitals=[]plaintext=''for i ininput:#解密 密文轉(zhuǎn)化成對(duì)應(yīng)數(shù)字for j in self.letters:if(i==j):digitals.append(self.letters[j])for keya in self.list_keya:a=self.Inverse(keya)for keyb inrange(0,26):for i in digitals:t=(keya*(i-keyb))%26for j in self.letters:if(t==self.letters[j]):plaintext=plaintext+jbreakprint(plaintext)plaintext=''defInverse(self, a,mod=26):#求秘鑰a的逆元 歐幾里得算法 x1,x2,x3 =1,0,mody1,y2,y3 =0,1,awhile(1):if(y3==0):g=x3breakif(y3==1):g=y3breakq=math.floor(x3/y3)#向下取整t1,t2,t3=x1-q*y1,x2-q*y2,x3-q*y3x1,x2,x3=y1,y2,y3y1,y2,y3=t1,t2,t3return y2 #逆元求得為y2,y3為gcd(a,26),最大公因數(shù) if __name__ =="__main__":test=Affine()#a=test.Inverse(615647919867658945209035999713482421889581801898774401730949,691310408299283134015133178155232316338199895735303344369216)#print(a)inputs=input("請(qǐng)輸入待加密明文:")a=int(input("請(qǐng)輸入秘鑰[a]:"))b=int(input("請(qǐng)輸入秘鑰[b]:"))test.Encrypt(a,b,inputs)test.Decrypt(a,b,test.ciphertext)s1 ="加密為:"+ test.ciphertexts2 ="解密為:"+ test.plaintexts3 =str(a)+"的逆元為: "+str(test.reverse)print(s1)print(s2)print(s3)#test.BruteForce(test.ciphertext)