码迷,mamicode.com
首页 > 其他好文 > 详细

[project euler]182RSA

时间:2017-09-05 01:41:18      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:get   mod   project   代码   http   观察   产生   ++i   ref   

https://projecteuler.net/problem=182

题意:

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

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

解答:

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

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

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

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

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

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

由上式可以看出,$ord(a) = b$

这里很容易联想到关于${a^k}\bmod {\rm{ }}n$的阶的公式,

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

变换一下位置,$ord({a^k})$ 就是使上式成立的$a$的可能取值

$(\varphi (p),k) = \frac{{\varphi (p)}}{{ord({a^k})}},(a,p) = = 1$

所以最初的解为$\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(n\log n)$

代码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\n",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\n",ans);
10 }

 

[project euler]182RSA

标签:get   mod   project   代码   http   观察   产生   ++i   ref   

原文地址:http://www.cnblogs.com/elpsycongroo/p/7476383.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!