Reference article Source: reait Home (http://www.reait.com/blog.html) Reprint Please specify, thank you for your cooperation.
in the Miller rabbin test Prime, the idea of a fast power-taking mode is used. Here is the summary.
A^b%c (This is known as the RSA public Key encryption method), when a is large, directly solve the problem is not likely
algorithm 1: Using the formula a*b%c= ((a%c) *b)%c, this processing is done at each step, which solves the problem that the a^b may be too large, but the time complexity of the algorithm is still not optimized code as follows:
on.intModexp_simple (intAintBintN) Geneva. { Geneva.intRET =1; Geneva. while(b--) to. { .. RET = A * ret%N; -. } ,.returnret; the.}
Algorithm 2: Another algorithm uses two points of thought, can reach O (logn).
You can expand B by binary to: b = P (n) *2^n + p (n-1) *2^ (n-1) +...+ P (1) * + P (0)
where P (i) (0<=i<=n) is 0 or 1
This a^b = a^ (P (n) *2^n + p (n-1) *2^ (n-1) +...+ P (1) * + P (0))
= a^ (P (n) *2^n) * a^ (P (n-1) *2^ (n-1)) *...* a^ (P (1) * *) * A^P (0)
For the case of P (i) =0, a^ (P (i) * 2^ (i-1)) = A^0 = 1, no processing
All we have to consider is the case of P (i) =1
Simplification:a^ (2^i) = a^ (2^ (i-1) * 2) = (a^ (P (i) * 2^ (i-1))) ^2 (important here!!) For details, see Qin Jiushao algorithm: http://baike.baidu.com/view/1431260.htm)
With this, we can recursively calculate all the a^ (2^i)
Of course by the conclusion of algorithm 1, we add modulo operations: a^ (2^i)%c = ((a^ (2^ (i-1))%c) * a^ (2^ (i-1)))%c
Then the a^ (2^i)%c that satisfies P (i) =1 is multiplied by the algorithm 1 and%c is the result, that is, the binary scan has been scanned from the highest bit to the lowest bit .
Instance code: Recursive
on.//Calculate A^BMODN Geneva.intModexp_recursion (intAintBintN)Geneva. { Geneva.intt =1; to. ..if(b = =0) -.return 1; ,. the.if(b = =1) Ten.returna%N; One. A. t = modexp_recursion (A, b>>1, N); -. -. t = t*t%N; the. -.if(b&0x1) -. { -. t = t*a%N; +. } -. +.returnT; A. }
Example code 2: Non-recursive optimization
on. #include <iostream> Geneva.using namespacestd; Geneva. Geneva.//Calculate A^BMODN to.intModexp (intAintBintN) .. { -.intret=1; ,.inttmp=A; the. while(b)Ten. { One.//Cardinality exists A.if(b&0x1) ret=ret*tmp%N; -. tmp=tmp*tmp%N; -. b>>=1; the. } -.returnret; -.} -. +.intMain () -. { +. Cout<<modexp (2,Ten,3) <<Endl; A.return 0; at.}
Fast Power-Take mode