python、C利用扩展欧几里得算法求乘法逆元 以及 实现仿射密码加解密

扩展欧几里得算法求乘法逆元

扩展的欧几里德算法可用于求解a mod b的逆元,而逆元求解在RSA加密算法中是不可缺少的一步

伪代码如下:
在这里插入图片描述

def fangshe_reverse(a,b):
    X=[0,1]
    Y=[1,0]
    X.append(int(a))
    Y.append(int(b))
    def exgcd(X,Y):
        if Y[2] == 0:
            pass
            #print('gcd(%d,%d)= %d \n no inverse'%(a,b,Y[2]))
        elif Y[2] == 1:
            pass
            #print('gcd(a,b)=%d\n a mod b的逆元: %d'%(int(Y[2]),int(Y[1])))
        else:
            Q= X[2] // Y[2]
            T1,T2,T3 = [(X[0] - Q * Y[0]),(X[1] - Q * Y[1]),(X[2] - Q * Y[2])]
            X[0],X[1],X[2] = Y[0],Y[1],Y[2]
            Y[0],Y[1],Y[2] = T1,T2,T3
            exgcd(X,Y)
    exgcd(X,Y)
    return int(Y[1])
#fangshe_reverse(3,17)

仿射密码实现加解密

算法实现核心:

仿射变换加密,并打印加密的结果
    c为密文,a和b为密钥(0<=a,b<=25)
    加密公式:c = a*m + b%26
    
仿射变换解密,并打印解密的结果
    c为密文,a和b为密钥
    0<=a,b<=25,且满足gcd(a,26)=1,a^-1表示a的逆元
    解密公式:m = (a^-1)*(c-b)%26

python实现代码:

# coding=utf-8
# author : rang

def menu():
    '''
    菜单
    '''
    print("-----------------------")
    print("|    0. 退出          |")
    print("|    1. 仿射加密  |")
    print("|    2. 仿射解密  |")
    print("-----------------------")

def gcd(a,b):
    #欧几里得算法求最大公约数
    if b == 0:
        return a
    else:
        return gcd(b , a % b)

def fangshe_reverse(a,b):
    X=[0,1]
    Y=[1,0]
    X.append(int(a))
    Y.append(int(b))
    def exgcd(X,Y):
        if Y[2] == 0:
            pass
            #print('gcd(a,b)= %d \n no inverse'%(a,b,Y[2]))
        elif Y[2] == 1:
            pass
            #print('gcd(a,b)=%d\n a mod b的逆元: %d'%(int(Y[2]),int(Y[1])))
        else:
            Q= X[2] // Y[2]
            T1,T2,T3 = [(X[0] - Q * Y[0]),(X[1] - Q * Y[1]),(X[2] - Q * Y[2])]
            X[0],X[1],X[2] = Y[0],Y[1],Y[2]
            Y[0],Y[1],Y[2] = T1,T2,T3
            exgcd(X,Y)
    exgcd(X,Y)
    return int(Y[1])
#fangshe_reverse(3,17)

def fangshe_encode(m,a,b):
    '''
    仿射变换加密,并打印加密的结果
    c为密文,a和b为密钥(0<=a,b<=25)
    加密公式:c = a*m + b%26
    '''
    c = ''
    for i in m:
        new_i = ord(i) - 97
        new_i =((a * new_i) + b ) % 26
        c += chr(new_i + 97)
    print("密文为:",c)     

def fangshe_decode(c,a,b):
    '''
    仿射变换解密,并打印解密的结果
    c为密文,a和b为密钥
    0<=a,b<=25,且满足gcd(a,26)=1,a^-1表示a的逆元
    解密公式:m = (a^-1)*(c-b)%26
    '''
    m = ''
    for i in c:
        new_i = ord(i) - 97
        #print(fangshe_reverse(a,26))
        new_i = (fangshe_reverse(a,26) * (int(new_i) - b)) % 26
        m += chr(new_i + 97)
    #print(m)
    print("明文为",m)

def input_a_b():
    a = int(input("请输入密钥a:"))
    while True:
        if gcd(a,26) != 1:
            print("密钥a与26不互素")
            a = int(input("请输入密钥a:"))
        else:
            break
    b = int(input("请输入密钥b:"))
    return a,b

if __name__=='__main__':
    while True:
        menu()
        choose = int(input("请选择: "))
        if choose == 1:
            m = input("请输入明文: ")
            a,b = input_a_b()
            fangshe_encode(m,a,b)
        elif choose == 2:            
            c = input("请输入密文: ")
            a,b = input_a_b()
            fangshe_decode(c,a,b)
        else:
            break

效果:
在这里插入图片描述

c实现代码:

#include <stdio.h>
#include <string.h>

char encode(int a,int b,char m[20]){
	//printf("%d",l);
	for (int i = 0; i < strlen(m); i++)
	{
		m[i] = (a*(m[i]-97)+b)%26+97;
		//printf("%s",s2);
	}
	printf("密文:%s\n",m);
	return 0;
}

int exgcd(int a,int b){
	int x[3] = {0,1,a};
	int y[3] = {1,0,26};
	int Q = 0;
	while(1){
		if (y[2] == 0){
			break;
		}
		else if (y[2] == 1){
			break;
		}
		else{
			Q = x[2] / y[2];
			int T1 = x[0] - Q * y[0];
			int T2 = x[1] - Q * y[1];
			int T3 = x[2] - Q * y[2];
			x[0] = y[0]; x[1] = y[1]; x[2] = y[2];
			y[0] = T1; y[1] = T2; y[2] = T3;
		}
	}
	printf("re_a:%d",(y[1] % 26 + 26) % 26);
	return (y[1] % 26 + 26) % 26;
}

int decode(int b,int _a,char c[20]){
	for (int i = 0; i < strlen(c); i++)
	{
		c[i] = (_a*((c[i]-97)-b) % 26 + 26)%26 + 97;          // 为负时加 26 再取模(与python有差异)
	}
	printf("明文:%s\n",c);
	return 1;
}

int main(){
	int a,b;
	char m[20],c[20];
	printf("-----------加密----------");
	printf("\n明文:");
	scanf("%s",&m);
	printf("\n密钥a:");
	scanf("%d",&a);
	printf("\n密钥b:");
	scanf("%d",&b);
	encode(a,b,m);

	printf("-----------解密----------");
	printf("\n密文:");
	scanf("%s",&c);
	printf("\n密钥a:");
	scanf("%d",&a);
	printf("\n密钥b:");
	scanf("%d",&b);
	decode(b,exgcd(a,26),c);
	return 0;
}


在这里插入图片描述

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值