冪模運算m^e (mod N),當m或者e很大時,其計算複雜度將非常高。因此希望有其他更快的計算方法,下面介紹二元法及M元法快速的運算方法。
一、二元法描述
在冪模運算中,比較常用的一種方法是二元法(也稱爲平方乘法),就是先將指數e以二進制表示法表示出來,即:
e=e0+e1×2+e2×2^2+.....+e(L-1)×2^(L-1)
於是運算過程爲:
m^e(mod N)=(...(m^(e(L-1))^2×m^(e(L-2))^2...m^e1)^2×m^e0 (mod N)
算法描述:
c←1
for i←L-1 downto 0
do
{
c←c^2 mod N
if e(i)=1
then c←c×m mod N
}
return(c)
如果將模N乘法運算與模N平方運算的計算複雜性的量級看做是相同的,則其計算複雜性爲O(log2 e)次模N乘法運算。
二、M元法描述
二元法是以二進制表示法爲基礎,所謂M元法,就是將e用M進制表示出來,再按照二元法計算方法進行冪模計算。下面對三元法算法進行描述。
算法描述:
c←1
for i←L-1 downto 0
do
{
c←c^3 mod N
if e(i)=1
then c←c×m mod N
if e(i)=2
then c←c×m^2 mod N
}
return(c)
三、C++實現二元法求快速冪模
#include<iostream>
using namespace std;
/*
遞歸實現十進制轉換成二進制存儲於e
*/
void conversion_binary(int a,string &e){
int b;
b=a%2;
if(a>=2){
conversion_binary(a/2,e);//遞歸
}
e+=b+'0';
}
int main()
{
string e;
long long c=1; //防止溢出
int i;
int m,a,N;
cout<<mod_fast(1268,24,154265)<<endl;
cout<<"形如m^a(mod N),請輸入m,a,N"<<endl;
cin>>m>>a>>N;
conversion_binary(a,e);//轉換二進制
i=e.size();
cout<<e<<endl;
//二元法主體
for(int j=0;j<i;j++){
c=(c*c)%N;
if(e[j]-'0'==1)//當e[j]=1時計算
c=(c*m)%N;
}
cout<<c<<endl;
return 0;
}
四、運行結果
五、常用求快速冪模或快速冪方法
long long mod_fast(long long a,int b,long long p)
{
long long aa=a,t=1;
while(b!=0)
{
if(b&1)//是b和1做二進制的且運算 即看b的最後邊那一位是不是1,是1的話 返回1 否則返回0
{
t=(t%p)*(aa%p)%p;
}
aa=(aa%p)*(aa%p)%p;
b=b/2;//aa平方模
}
return t%p;
}
int main()
{
cout<<mod_fast(1268,24,154265)<<endl;
return 0;
}