RSA加密(快速幂求余)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
快速幂求余算法
(OJ T1128)
求a^b%c(这就是著名的RSA公钥的加密方法)
当a,b很大时,直接求解这个问题不太可能,你能想到哪些优化呢?
算法1:直观上,也许最容易想到的是利用
a*b%c=((a%c)*b)%c,这样每一步都进行这种处理,这就解决了a^b可能太大存不下的问题,但这个算法的时间复杂度依然是O(n),根本没有得到优化。当b很大时运行时间会很长
算法2:另一种算法利用了分治的思想,可以达到O(logn)。
可以把b按二进制展开为
b=p(n)*2^n+p(n-1)*2^(n-1)+...+p(1)*2+p(0)其中p(i) (0<=i<=n)为0或1
这样a^b=a^(p(n)*2^n+p(n-1)*2^(n-1)+...+p(1)*2+p(0)) =a^(p(n)*2^n)*a^(p(n-1)*2^(n-1)*...*a^(p(1)*2)*a^p(0)
对于p(i)=0的情况,a^p(i)*2^(i-1)=a^0=1,不用处理,我们要考虑的仅仅是p(i)=1的情况,
a^(2^i)=(a^(p(i)*2(i-1)))^2 (当p(i)=1时,
a^(2^i)=(a^(2(i-1)))^2)
利用这一点,我们可以递推地算出所有的a^(2^i)
当然由算法1的结论a*b%c=((a%c)*b)%c,我们加上取模运算
a^(2^i)%c=((a^(2(i-1))%c)*a^(2(i-1)))%c 于是再把所有满足p(i)=1的a^(2^i)%c按照算法1乘起来再%c就是结果
示例:
3^6%7=3^(2^2)*3^(2^1)%7
=((3^(2^1))^2%7)*(3^1*3^1%7)
=(((3^1*3^1%7)%7)^2%7*2%7)%7
=(4*2)%7
=8%7
=1
当然算法可以进一步改进,比如二进制的每一位不必存起来,可以边求边用
经改进后代码如下:(输入a,k,m,求a^k%m)
long f(long a,long k,long m)
{
long b=1;
while(k>=1)
{
if(k%2==1) b=a*b%m;
a=a*a%m;
k=k/2;
}
return b;
}
例题
一、高级机密
Time Limit:1000MS Memory Limit:65536K
Total Submit:43 Accepted:16
Description
在很多情况下,我们需要对信息进行加密。特别是随着Internet的飞速发展,加密技术就显得尤为重要。
很早以前,罗马人为了在战争中传递信息,频繁地使用替换法进行信息加密。然而在计算机技术高速发展的今天,这种替换法显得不堪一击。因此研究人员正在试图寻找一种易于编码、但不易于解码的编码规则。
目前比较流行的编码规则称为RSA,是由美国麻省理工学院的三位教授发明的。这种编码规则是基于一种求幂取模算法的:对于给出的三个正整数a,b,c,计算a的b次方除以c的余数。
你的任务是编写一个程序,计算a b mod c。
Input
输入数据只有一行,依次为三个正整数a,b,c,三个正整数之间各以一个空格隔开,并且1<=a,b < c < =32768。
Output
输出只有一个整数表示计算结果。
Sample Input
2 6 11
Sample Output
9
解:
import ;
//对于给出的三个正整数a,b,c,计算a的b次方除以c的余数,即:a^b mod c //相关公式:用二进制表示b:
b=p(n)*2^n+p(n-1)*2^(n-1)+...+p(1)*2+p(0) (其中p(i)值为0或1)
//则a^b=a^(p(n)*2^n+p(n-1)*2^(n-1)+...+p(1)*2+p(0))
//=a^(p(n)*2^n)*a^(p(n-1)*2^(n-1))*...*a^(p(1)*2)*a^p(0) public class TopSecret {
public static void main(String[] args) { long a,b,c;
Scanner input=new Scanner(System.in);
a=input.nextInt();
b=input.nextInt();
c=input.nextInt();
,b,c));
}
public static long getPowMod(long a,long b,long c){
long result=1;
while(b>=1){
if(b%2==1) result=a*result%c;
a=a*a%c;
b/=2; //通过b/2来求得p(i)为1还是0
}
return result;
}
}
二、D: Raising Modulo Numbers
Time Limit: 1000 ms Case Time Limit: 1000
ms Memory Limit: 30000 KB
Submit: 24 Accepted: 7
Description
People are different. Some secretly read magazines full of interesting girls' pictures, others create an A-bomb in their cellar, others like using Windows, and some like difficult mathematical games. Latest marketing research shows, that this market segment was so far underestimated and that there is lack of such games. This kind of game was thus included into the
KOKODáKH. The rules follow: