• [PE182]RSA encryption


    https://projecteuler.net/problem=182

    题意:

    找出满足下列条件的所有$e$ 的和,

    - $1 < e < varphi left( {1009,3643} ight)$
    - $gcd(e,φ)=1$
    - 满足${m^e} equiv m{ m{ }}mod { m{ }}n$ 的$m$的个数最小

    解答:

    这道题最重要的就是解决这个问题:

    ${m^e} equiv m{ m{ }}mod { m{ }}n$ 中$e$确定时,$m$的取值的个数。

    由于n是合数,且 $n = p*q$ ,所以先考虑${m^e} equiv m{ m{ }}mod { m{ }}p$ 和 ${m^e} equiv m{ m{ }}mod { m{ }}q$ ,

    $m({m^{e - 1}} - 1) equiv 0{ m{ }}mod { m{ }}p$ , $p$ 是质数

    - $m==0$ ,恒成立
    - $m!=0$ ,${m^{e - 1}} equiv 1mod { m{ }}p$

    考虑 ${a^b} equiv 1mod p$ ,$a$ 、$p$ 互素,此式中$b$确定时,$a$的个数

    因为$p$ 为素数,所以必存在原根$r$ ,使得$ a= {r^k}$ ,

    ${r^{kb}} = 1{ m{ }}mod { m{ }}p$

    这里很容易联想到关于${a^k}mod { m{ }}p$的阶那个公式,

    $ord({r^b}) = frac{{varphi (p)}}{{(varphi (p),b)}},(r,p) = = 1$

    变换一下位置,

    $(varphi (p),b) = frac{{varphi (p)}}{{ord({r^b})}},(r,p) = = 1$

    ${r^{ord({r^b})}}$ ,${r^{2ord({r^b})}}$ ,...,${r^{(varphi (p ),b )ord({r^b})}}$就是使上式成立的$a$的可能取值,

    所以左边就是解的个数。

    所以最初的解为$gcd (varphi (p),b) = gcd (p - 1,b)$

    回到上面,还有$m==0$ 的情况,

    所以解为$gcd (varphi (p),b)+1 = gcd (p - 1,b)+1$

    再看如何解决模数不为质数的问题,这里 就需要用到中国剩余定理,根据中国剩余定理,每一对$p$ 和 $q$ ,就会产生一个解,依据乘法原理,所以最后的解为$[gcd (p - 1,e - 1) + 1]*[gcd (q - 1,e - 1) + 1]$

    接下来:就是枚举$e$ 的问题了

    - 直接进行暴力

    - 观察$e$,因为$gcd ((p - 1)(q - 1),e ) = = 1$ ,故$e$ 为奇数,$e-1$ 为偶数, $gcd (e - 1,p - 1) > = 2$ ,

    $gcd (e - 1,q - 1) > = 2$ ,这里确定了两个gcd的下界的最小值,而且显然这两个下界在枚举$e$ 的过程中是可以取到的,所以这里可以直接判断最小的情况。

    复杂度:$O(nlog n)$ ,其中$logn$ 是辗转相除的复杂度,证明见维基百科。

    代码1:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll inf=1<<30;
     5 ll p=1009,q=3643,factor[4070000];
     6 ll n=q*p,phi=(p-1)*(q-1),mi=inf,ans;
     7 int main(){
     8     for(ll i=2;i<phi;++i)    if(__gcd(i,phi)==1) factor[i]=(__gcd(i-1,p-1)+1)*(__gcd(i-1,q-1)+1),mi=min(mi,factor[i]);
     9     for(ll i=2;i<phi;++i)    if(factor[i]==mi)    ans+=i;
    10     printf("%lld
    ",ans);
    11 }

    代码2:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll inf=1<<30;
     5 ll p=1009,q=3643;
     6 ll n=q*p,phi=(p-1)*(q-1),ans;
     7 int main(){
     8      for(ll i=3;i<phi;++i)    if(__gcd(i,phi)==1&&__gcd(i-1,q-1)==2&&__gcd(i-1,p-1)==2) ans+=i;
     9      printf("%lld
    ",ans);
    10 }
  • 相关阅读:
    vue多项目的工程化部署
    vue+element项目部署到线上,icon图标不显示
    elementui的表格嵌套表单及校验demo
    借鉴微信小程序表单校验wxValidate的源码里边的正则
    vue中el-upload上传多图片且携带参数,批量而不是一张一张的解决方案
    Maven笔记
    《图解HTTP》摘要
    Java面向对象
    MySQL数据库学习记录
    Python二维数组操作
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7476383.html
Copyright © 2020-2023  润新知