gcd&&extend_gcd

一、gcd:

int gcd(int a,int b){return b==0?a:gcd(b,a%b);}

二、extend_gcd:

int extend_gcd(int a,int b,int &x,int &y)
{
    if(b==0){
        x=1;y=0;
        return a;
    }
    else{
        int result=extend_gcd(b,a%b,y,x);
        y-=x*(a/b);
        return result;
    }
}

注:用于求出a,b的最大公约数,且求出x,y满足:ax+by=gcd(a,b)

下面给出相关证明:

1、当b=0时,ax+by=gcd(a,0)=a,所以此时x=1,y=0

2、当b>0时,在欧几里得算法的基础上,已知:

因为:gcd(a,b)=gcd(b,a%b);

           当前状态gcd(a,b)=a*x1+b*y1;

所以:下一状态(即:令a=b,b=a%b):gcd(b,a%b)=b*x2+(a%b)*y2=gcd(a,b);@

因为:a%b=a-(a/b)*b(即:余数=被除数-除数的最大整数倍)

所以上式@可化为:b*x2+(a-(a/b)*b)*y2=gcd(a,b)

进一步化简得:a*y2+b*(x2-(a/b)*y2)=gcd(a,b)

因为最初的状态:gcd(a,b)=a*x1+b*y1:

 递推得到的状态:gcd(a,b)=a*y2+b*(x2-(a/b)*y2)

所以:a*x1+b*y1=a*y2+b*(x2-(a/b)*y2)

两边相比可得:x1=y2

                         y1=x2-(a/b)*y2=x2-(a/b)*x1

完整测试代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

int gcd(int a,int b){return b==0?a:gcd(b,a%b);}

int extend_gcd(int a,int b,int &x,int &y)
{
    if(b==0){
        x=1;y=0;
        return a;
    }
    else{
        int result=extend_gcd(b,a%b,y,x);
        y-=x*(a/b);
        return result;
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int a,b,x,y;
    cin>>a>>b;
    //int ans=gcd(a,b);
    int ans=extend_gcd(a,b,x,y);
    cout<<ans<<" "<<x<<" "<<y<<endl;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
import random def fastExpMod(a, e, m): a = a % m res = 1 while e != 0: if e&1: res = (res * a) % m e >>= 1 #右移一位 a = (a * a) % m return res # 求最大公约数 def gcd(a, b): if b == 0: return a else: return gcd(b, a % b) # 扩展欧几里德算法求逆元 def extend_gcd(a, b): if b == 0: return 1, 0 else: x, y = extend_gcd(b, a % b) x, y = y, x - (a // b) * y return x, y # ElGamal密钥生成 def generate_key(p, g, x): y = pow(g, x, p) return (p, g, y, x), (p, g, y) # ElGamal加密 def encrypt(p, g, y, m): #Bob -- 加密 r = fastExpMod(g, k, p) c = (m * fastExpMod(y, k, p)) % p return r, c # ElGamal解密 def decrypt(ciphertext, private_key): r, c = ciphertext _, _, y = private_key k_inverse = extend_gcd(pow(r, p - 1 - y, p), p)[0] msg = chr((k_inverse * c) % p) return msg # 用户输入素数p和生成元g p = int(input("请输入一个大素数p:")) g = int(input("请输入一个在模p下的生成元g:")) # 用户输入私钥x和明文m x = int(input("请输入一个小于p-1的私钥x:")) m = input("请输入需要加密的明文m:") k= int(input('请输入一个随机数k:')) y = fastExpMod(g, k, p) # 生成ElGamal公钥和私钥 public_key, private_key = generate_key(p, g, x) # 对消息进行加密 ciphertext = encrypt(p, g, y, m) # 对密文进行解密 decrypted_msg = decrypt(ciphertext, private_key) # 输出结果 print(f"原始消息: {m}") print(f"加密后的消息: {ciphertext}") print(f"解密后的消息: {decrypted_msg}",改代码有误问题
最新发布
06-10

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值