密码学-仿射加密 一谈

原理

  • 将字母编码成一个表,规定A=0,一直到Z=25,共26个字母
ABCDEFGHIJKLMNOPQRSTUVWXYZ
012345678910111213141516171819202122232425
加密
  • 给出一个仿射函数,形如Y=(aX+b)mod 26,且a,26互质。其中X表示明文输入,Y表示密文输出。
解密
  • 将加密函数进行求逆,即对aG(n-1),n=26的乘法逆元,令 E(a) 表示a的乘法逆元,则解密函数为X=(E(a)(Y-b))mod 26,其中Y为密文输入,X为明文输出。
  • 还有种情况就是只给了b,这样的话,就要找出1~25中所有与26互质的数,并求其乘法逆元。

脚本

#encoding=utf-8

def xgcd(a,b,n):
    if b==0:
        return 1,0,a
    x,y,g=xgcd(b,a%b,n)
    t=x
    x=y
    y=t-(a//b)*x
    return x%n,y%n,g
def gcd(a,b):
    if b==0:
        return a
    return gcd(b,a%b)

def get_a():
    a_buf=[]
    for i in range(1,26):
        if gcd(i,26)==1:
            x,y,g=xgcd(i,26,26)
            a_buf.append(x)
    return a_buf

def FS_Encrypt(plaintext,a,b,m):
    ret=''
    for c in plaintext.upper():
        ret+=chr((((ord(c)-65)*a+b)%26)+65)
    if m==0:
        return ret
    else:
        return ret.lower()

def FS_Decrypt(cipher,a,b,m):
    ret=[]
    tmp=''
    if a==0:
        a_buf=get_a()
        for ta in a_buf:
            tmp=''
            for c in cipher.upper():
                tmp+=chr((ta*((ord(c)-65)-b)%26)+65)
            if m==0:
                ret.append(tmp)
            else:
                ret.append(tmp.lower())
        return ret
    else:
        x,y,g=xgcd(a,26,26)
        for c in cipher.upper():
            tmp+=chr((x*((ord(c)-65)-b)%26)+65)
        if m==0:
            ret.append(tmp)
        else:
            ret.append(tmp.lower())
        return ret

print '[*] 1.加密,2.解密:'
f=int(raw_input())
if f==1:
    print '[*] 请输入明文:'
    plaintext=raw_input()
    print '[*] 请输入a:'
    a=int(raw_input())
    print '[*] 请输入b:'
    b=int(raw_input())
    print '[*] 0.输出为大写,1.输出为小写:'
    m=int(raw_input())
    print FS_Encrypt(plaintext,a,b,m)
else:
    if f==2:
        print '[*] 请输入密文:'
        cipher=raw_input()
        print '[*] 请输入a:'
        a=int(raw_input())
        print '[*] 请输入b:'
        b=int(raw_input())
        print '[*] 0.输出为大写,1.输出为小写:'
        m=int(raw_input())
        print FS_Decrypt(cipher,a,b,m)

测试

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值