转载  大整数运算类 收藏

使用时需要将Project->Settings->C/C++->CodeGeneration->UseRuntimeLibrary设置为Debug MultiThreaded

/*****************************************************************
大数运算库头文件:BigInt.h
作者:fangle.liu@gmail.com
版本:1.2 (2003.5.13)
说明:适用于MFC,1024位RSA运算
****************************************************************
*/


#include 
<cmath>
#include 
<afx.h>    //

#define BI_MAXLEN 40
#define DEC 10
#define HEX 16

//小素数表
const static int PrimeTable[1230]=
{   3,    5,    7,    11,   13,   17,   19,   23,   29,   31,
    
37,   41,   43,   47,   53,   59,   61,   67,   71,   73,
    
79,   83,   89,   97,   101,  103,  107,  109,  113,  127
    
131,  137,  139,  149,  151,  157,  163,  167,  173,  179
    
181,  191,  193,  197,  199,  211,  223,  227,  229,  233
    
239,  241,  251,  257,  263,  269,  271,  277,  281,  283
    
293,  307,  311,  313,  317,  331,  337,  347,  349,  353
    
359,  367,  373,  379,  383,  389,  397,  401,  409,  419
    
421,  431,  433,  439,  443,  449,  457,  461,  463,  467
    
479,  487,  491,  499,  503,  509,  521,  523,  541,  547
    
557,  563,  569,  571,  577,  587,  593,  599,  601,  607
    
613,  617,  619,  631,  641,  643,  647,  653,  659,  661
    
673,  677,  683,  691,  701,  709,  719,  727,  733,  739
    
743,  751,  757,  761,  769,  773,  787,  797,  809,  811
    
821,  823,  827,  829,  839,  853,  857,  859,  863,  877,
    
881,  883,  887,  907,  911,  919,  929,  937,  941,  947
    
953,  967,  971,  977,  983,  991,  997,  100910131019
    
1021103110331039104910511061106310691087,
    
1091109310971103110911171123112911511153
    
1163117111811187119312011213121712231229
    
1231123712491259127712791283128912911297
    
1301130313071319132113271361136713731381,
    
1399140914231427142914331439144714511453
    
1459147114811483148714891493149915111523,
    
1531154315491553155915671571157915831597
    
1601160716091613161916211627163716571663
    
1667166916931697169917091721172317331741
    
1747175317591777178317871789180118111823
    
1831184718611867187118731877187918891901
    
1907191319311933194919511973197919871993
    
1997199920032011201720272029203920532063,
    
2069208120832087208920992111211321292131
    
2137214121432153216121792203220722132221
    
2237223922432251226722692273228122872293,
    
2297230923112333233923412347235123572371,
    
2377238123832389239323992411241724232437
    
2441244724592467247324772503252125312539
    
2543254925512557257925912593260926172621
    
2633264726572659266326712677268326872689
    
2693269927072711271327192729273127412749
    
2753276727772789279127972801280328192833
    
2837284328512857286128792887289729032909,
    
2917292729392953295729632969297129993001,
    
3011301930233037304130493061306730793083,
    
3089310931193121313731633167316931813187
    
3191320332093217322132293251325332573259
    
3271329933013307331333193323332933313343,
    
3347335933613371337333893391340734133433
    
3449345734613463346734693491349935113517
    
3527352935333539354135473557355935713581,
    
3583359336073613361736233631363736433659
    
3671367336773691369737013709371937273733
    
3739376137673769377937933797380338213823
    
3833384738513853386338773881388939073911
    
3917391939233929393139433947396739894001,
    
4003400740134019402140274049405140574073
    
4079409140934099411141274129413341394153
    
4157415941774201421142174219422942314241
    
4243425342594261427142734283428942974327
    
4337433943494357436343734391439744094421
    
4423444144474451445744634481448344934507
    
4513451745194523454745494561456745834591
    
4597460346214637463946434649465146574663
    
4673467946914703472147234729473347514759
    
4783478747894793479948014813481748314861
    
4871487748894903490949194931493349374943
    
4951495749674969497349874993499950035009
    
5011502150235039505150595077508150875099
    
5101510751135119514751535167517151795189
    
5197520952275231523352375261527352795281
    
5297530353095323533353475351538153875393
    
5399540754135417541954315437544154435449
    
5471547754795483550155035507551955215527
    
5531555755635569557355815591562356395641
    
5647565156535657565956695683568956935701
    
5711571757375741574357495779578357915801
    
5807581358215827583958435849585158575861
    
5867586958795881589759035923592759395953
    
5981598760076011602960376043604760536067
    
6073607960896091610161136121613161336143
    
6151616361736197619962036211621762216229
    
6247625762636269627162776287629963016311
    
6317632363296337634363536359636163676373
    
6379638963976421642764496451646964736481
    
6491652165296547655165536563656965716577
    
6581659966076619663766536659666166736679
    
6689669167016703670967196733673767616763
    
6779678167916793680368236827682968336841
    
6857686368696871688368996907691169176947
    
6949695969616967697169776983699169977001
    
7013701970277039704370577069707971037109
    
7121712771297151715971777187719372077211
    
7213721972297237724372477253728372977307
    
7309732173317333734973517369739374117417
    
7433745174577459747774817487748974997507
    
7517752375297537754175477549755975617573
    
7577758375897591760376077621763976437649
    
7669767376817687769176997703771777237727
    
7741775377577759778977937817782378297841
    
7853786778737877787978837901790779197927
    
7933793779497951796379938009801180178039
    
8053805980698081808780898093810181118117
    
8123814781618167817181798191820982198221
    
8231823382378243826382698273828782918293
    
8297831183178329835383638369837783878389
    
8419842384298431844384478461846785018513
    
8521852785378539854385638573858185978599
    
8609862386278629864186478663866986778681
    
8689869386998707871387198731873787418747
    
8753876187798783880388078819882188318837
    
8839884988618863886788878893892389298933
    
8941895189638969897189999001900790119013
    
9029904190439049905990679091910391099127
    
9133913791519157916191739181918791999203
    
9209922192279239924192579277928192839293
    
9311931993239337934193439349937193779391
    
9397940394139419942194319433943794399461
    
9463946794739479949194979511952195339539
    
9547955195879601961396199623962996319643
    
9649966196779679968996979719972197339739
    
9743974997679769978197879791980398119817
    
9829983398399851985798599871988398879901
    
9907992399299931994199499967997310007,10009,
}
;

const static CString CharTable="0123456789abcdefghijklmnopqrstuvwxyz"

class CBigInt
{
public:
//大数在0x100000000进制下的长度    
    unsigned m_nLength;
//用数组记录大数在0x100000000进制下每一位的值
    unsigned long m_ulValue[BI_MAXLEN];

    CBigInt();

/*****************************************************************
基本操作与运算
Mov,赋值运算,可赋值为大数或普通整数,可重载为运算符“=”
Cmp,比较运算,可重载为运算符“==”、“!=”、“>=”、“<=”等
Add,加,求大数与大数或大数与普通整数的和,可重载为运算符“+”
Sub,减,求大数与大数或大数与普通整数的差,可重载为运算符“-”
Mul,乘,求大数与大数或大数与普通整数的积,可重载为运算符“*”
Div,除,求大数与大数或大数与普通整数的商,可重载为运算符“/”
Mod,模,求大数与大数或大数与普通整数的模,可重载为运算符“%”
Sqr,开方,求大数的算术平方根
****************************************************************
*/

    
void Mov(unsigned __int64 A);
    
void Mov(CBigInt& A);
    CBigInt Add(CBigInt
& A);
    CBigInt Sub(CBigInt
& A);
    CBigInt Mul(CBigInt
& A);
    CBigInt Div(CBigInt
& A);
    CBigInt Mod(CBigInt
& A);
    CBigInt Sqrt();
    CBigInt Add(unsigned 
long A);
    CBigInt Sub(unsigned 
long A);
    CBigInt Mul(unsigned 
long A);
    CBigInt Div(unsigned 
long A);
    unsigned 
long Mod(unsigned long A); 
    
int Cmp(CBigInt& A); 

/*****************************************************************
输入输出
Get,从字符串按10进制或16进制格式输入到大数
Put,将大数按10进制或16进制格式输出到字符串
****************************************************************
*/

    
void Get(CString& str, unsigned int system=HEX);
    
void Put(CString& str, unsigned int system=HEX);

/*****************************************************************
RSA相关运算
ModMul,布莱克雷算法求模乘
ModInv,欧几里德算法求模逆
MonPro,蒙哥马利算法求模乘
ModExp,蒙哥马利算法求模幂
TestPrime,拉宾米勒算法进行素数测试
FindPrime,产生指定长度的随机大素数
****************************************************************
*/

    CBigInt ModMul(CBigInt
& A, CBigInt& B);
    CBigInt ModInv(CBigInt
& A);
    CBigInt MonPro(CBigInt
& A, CBigInt& B, unsigned long n);
    CBigInt ModExp(CBigInt
& A, CBigInt& B);
    
int TestPrime();
    
void FindPrime(int bits);
}
;

/*****************************************************************
大数运算库源文件:BigInt.cpp
作者:fangle.liu@gmail.com
版本:1.2 (2003.5.13)
说明:适用于MFC,1024位RSA运算
****************************************************************
*/

#include 
"stdafx.h"
#include 
"BigInt.h"

//构造大数对象并初始化为零
CBigInt::CBigInt()
{
    m_nLength
=1;
    
for(int i=0;i<BI_MAXLEN;i++)m_ulValue[i]=0;
}


/****************************************************************************************
大数比较
调用方式:N.Cmp(A)
返回值:若N<A返回-1;若N=A返回0;若N>A返回1
***************************************************************************************
*/

int CBigInt::Cmp(CBigInt& A)
{
    
if(m_nLength>A.m_nLength)return 1;
    
if(m_nLength<A.m_nLength)return -1;
    
for(int i=m_nLength-1;i>=0;i--)
    
{
        
if(m_ulValue[i]>A.m_ulValue[i])return 1;
        
if(m_ulValue[i]<A.m_ulValue[i])return -1;
    }

    
return 0;
}


/****************************************************************************************
大数赋值
调用方式:N.Mov(A)
返回值:无,N被赋值为A
***************************************************************************************
*/

void CBigInt::Mov(CBigInt& A)
{
    m_nLength
=A.m_nLength;
    
for(int i=0;i<BI_MAXLEN;i++)m_ulValue[i]=A.m_ulValue[i];
}


void CBigInt::Mov(unsigned __int64 A)
{
    
if(A>0xffffffff)
    
{
        m_nLength
=2;
        m_ulValue[
1]=(unsigned long)(A>>32);
        m_ulValue[
0]=(unsigned long)A;
    }

    
else
    
{
        m_nLength
=1;
        m_ulValue[
0]=(unsigned long)A;
    }

    
for(int i=m_nLength;i<BI_MAXLEN;i++)m_ulValue[i]=0;
}


/****************************************************************************************
大数相加
调用形式:N.Add(A)
返回值:N+A
***************************************************************************************
*/

CBigInt CBigInt::Add(CBigInt
& A)
{
    CBigInt X;
    X.Mov(
*this);
    unsigned carry
=0;
    unsigned __int64 sum
=0;
    
if(X.m_nLength<A.m_nLength)X.m_nLength=A.m_nLength;
    
for(unsigned i=0;i<X.m_nLength;i++)
    
{
        sum
=A.m_ulValue[i];
        sum
=sum+X.m_ulValue[i]+carry;
        X.m_ulValue[i]
=(unsigned long)sum;
        carry
=(unsigned)(sum>>32);
    }

    X.m_ulValue[X.m_nLength]
=carry;
    X.m_nLength
+=carry;
    
return X;
}


CBigInt CBigInt::Add(unsigned 
long A)
{
    CBigInt X;
    X.Mov(
*this);
    unsigned __int64 sum;
    sum
=X.m_ulValue[0];
    sum
+=A;
    X.m_ulValue[
0]=(unsigned long)sum;
    
if(sum>0xffffffff)
    
{
        unsigned i
=1;
        
while(X.m_ulValue[i]==0xffffffff){X.m_ulValue[i]=0;i++;}
        X.m_ulValue[i]
++;
        
if(X.m_nLength==i)X.m_nLength++;
    }

    
return X;
}


/****************************************************************************************
大数相减
调用形式:N.Sub(A)
返回值:N-A
***************************************************************************************
*/

CBigInt CBigInt::Sub(CBigInt
& A)
{
    CBigInt X;
    X.Mov(
*this);
    
if(X.Cmp(A)<=0){X.Mov(0);return X;}
    unsigned carry
=0;
    unsigned __int64 num;
    unsigned i;
    
for(i=0;i<m_nLength;i++)
    
{
        
if((m_ulValue[i]>A.m_ulValue[i])||((m_ulValue[i]==A.m_ulValue[i])&&(carry==0)))
        
{
            X.m_ulValue[i]
=m_ulValue[i]-carry-A.m_ulValue[i];
            carry
=0;
        }

        
else
        
{
            num
=0x100000000+m_ulValue[i];
            X.m_ulValue[i]
=(unsigned long)(num-carry-A.m_ulValue[i]);
            carry
=1;
        }

    }

    
while(X.m_ulValue[X.m_nLength-1]==0)X.m_nLength--;
    
return X;
}


CBigInt CBigInt::Sub(unsigned 
long A)
{
    CBigInt X;
    X.Mov(
*this);
    
if(X.m_ulValue[0]>=A){X.m_ulValue[0]-=A;return X;}
    
if(X.m_nLength==1){X.Mov(0);return X;}
    unsigned __int64 num
=0x100000000+X.m_ulValue[0];
    X.m_ulValue[
0]=(unsigned long)(num-A);
    
int i=1;
    
while(X.m_ulValue[i]==0){X.m_ulValue[i]=0xffffffff;i++;}
    X.m_ulValue[i]
--;
    
if(X.m_ulValue[i]==0)X.m_nLength--;
    
return X;
}


/****************************************************************************************
大数相乘
调用形式:N.Mul(A)
返回值:N*A
***************************************************************************************
*/

CBigInt CBigInt::Mul(CBigInt
& A)
{
    
if(A.m_nLength==1)return Mul(A.m_ulValue[0]);
    CBigInt X;
    unsigned __int64 sum,mul
=0,carry=0;
    unsigned i,j;
    X.m_nLength
=m_nLength+A.m_nLength-1;
    
for(i=0;i<X.m_nLength;i++)
    
{
        sum
=carry;
        carry
=0;
        
for(j=0;j<A.m_nLength;j++)
        
{
            
if(((i-j)>=0)&&((i-j)<m_nLength))
            
{
                 mul
=m_ulValue[i-j];
                 mul
*=A.m_ulValue[j];
                 carry
+=mul>>32;
                 mul
=mul&0xffffffff;
                 sum
+=mul;
            }

        }

        carry
+=sum>>32;
        X.m_ulValue[i]
=(unsigned long)sum;
    }

    
if(carry){X.m_nLength++;X.m_ulValue[X.m_nLength-1]=(unsigned long)carry;}
    
return X;
}


CBigInt CBigInt::Mul(unsigned 
long A)
{
    CBigInt X;
    unsigned __int64 mul;
    unsigned 
long carry=0;
    X.Mov(
*this);
    
for(unsigned i=0;i<m_nLength;i++)
    
{
        mul
=m_ulValue[i];
        mul
=mul*A+carry;
        X.m_ulValue[i]
=(unsigned long)mul;
        carry
=(unsigned long)(mul>>32);
    }

    
if(carry){X.m_nLength++;X.m_ulValue[X.m_nLength-1]=carry;}
    
return X;
}


/****************************************************************************************
大数相除
调用形式:N.Div(A)
返回值:N/A
***************************************************************************************
*/

CBigInt CBigInt::Div(CBigInt
& A)
{
    
if(A.m_nLength==1)return Div(A.m_ulValue[0]);
    CBigInt X,Y,Z;
    unsigned i,len;
    unsigned __int64 num,div;
    Y.Mov(
*this);
    
while(Y.Cmp(A)>=0)
    
{       
        div
=Y.m_ulValue[Y.m_nLength-1];
        num
=A.m_ulValue[A.m_nLength-1];
        len
=Y.m_nLength-A.m_nLength;
        
if((div==num)&&(len==0)){X.Mov(X.Add(1));break;}
        
if((div<=num)&&len){len--;div=(div<<32)+Y.m_ulValue[Y.m_nLength-2];}
        div
=div/(num+1);
        Z.Mov(div);
        
if(len)
        
{
            Z.m_nLength
+=len;
            
for(i=Z.m_nLength-1;i>=len;i--)Z.m_ulValue[i]=Z.m_ulValue[i-len];
            
for(i=0;i<len;i++)Z.m_ulValue[i]=0;
        }

        X.Mov(X.Add(Z));
        Y.Mov(Y.Sub(A.Mul(Z)));
    }

    
return X;
}


CBigInt CBigInt::Div(unsigned 
long A)
{
    CBigInt X;
    X.Mov(
*this);
    
if(X.m_nLength==1){X.m_ulValue[0]=X.m_ulValue[0]/A;return X;}
    unsigned __int64 div,mul;
    unsigned 
long carry=0;
    
for(int i=X.m_nLength-1;i>=0;i--)
    
{
        div
=carry;
        div
=(div<<32)+X.m_ulValue[i];
        X.m_ulValue[i]
=(unsigned long)(div/A);
        mul
=(div/A)*A;
        carry
=(unsigned long)(div-mul);
    }

    
if(X.m_ulValue[X.m_nLength-1]==0)X.m_nLength--;
    
return X;
}


/****************************************************************************************
大数求模
调用形式:N.Mod(A)
返回值:N%A
***************************************************************************************
*/

CBigInt CBigInt::Mod(CBigInt
& A)
{
    CBigInt X,Y;
    unsigned __int64 div,num;
    unsigned 
long carry=0;
    unsigned i,len;
    
int n;
    n
=Cmp(A);
    
if(n<0)return A;
    
if(n=0)return X;
    X.Mov(
*this);
    
while(1)
    
{
        div
=X.m_ulValue[X.m_nLength-1];
        num
=A.m_ulValue[A.m_nLength-1];
        len
=X.m_nLength-A.m_nLength;
        
if((div<=num)&&len){len--;div=(div<<32)+X.m_ulValue[X.m_nLength-2];}
        div
=div/(num+1);
        Y.Mov(div);
        Y.Mov(A.Mul(Y));
        
if(len)
        
{
            Y.m_nLength
+=len;
            
for(i=Y.m_nLength-1;i>=len;i--)Y.m_ulValue[i]=Y.m_ulValue[i-len];
            
for(i=0;i<len;i++)Y.m_ulValue[i]=0;
        }

        X.Mov(X.Sub(Y));
        n
=X.Cmp(A);
        
if(n==0){X.Mov(0);return X;}
        
if(n<0)return X;
    }

}


unsigned 
long CBigInt::Mod(unsigned long A)
{
    
if(m_nLength==1)return(m_ulValue[0]%A);
    unsigned __int64 div;
    unsigned 
long carry=0;
    
for(int i=m_nLength-1;i>=0;i--)
    
{
        div
=m_ulValue[i];
        div
+=carry*0x100000000;
        carry
=(unsigned long)(div%A);
    }

    
return carry;
}


/****************************************************************************************
大数开方
调用形式:N.Sqr()
返回值:N的算术平方根
***************************************************************************************
*/

CBigInt CBigInt::Sqrt()
{
    CBigInt X,M,N;
    unsigned 
long m,n;
    n
=m_ulValue[m_nLength-1];
    n
=(unsigned long)sqrt((double)n);
    m
=n+1;
    
if(m_nLength==1){X.Mov(n);return X;}
    N.m_nLength
=m_nLength/2;
    M.m_nLength
=N.m_nLength;
    
if(m_nLength&1)
    
{
        M.m_nLength
++;
        N.m_nLength
++;
        M.m_ulValue[M.m_nLength
-1]=m;
        N.m_ulValue[N.m_nLength
-1]=n;
    }

    
else 
    
{
        M.m_ulValue[M.m_nLength
-1]=(m<<16);
        N.m_ulValue[N.m_nLength
-1]=(n<<16);
    }

    X.Mov(M.Add(N));
    X.Mov(X.Div(
2));
    
while(1)
   
{
        
if(Cmp(X.Mul(X))<0)M.Mov(X);
        
else N.Mov(X);
        X.Mov(M.Sub(N));
        
if((X.m_ulValue[0]==1)&&(X.m_nLength==1))return N;
        X.Mov(M.Add(N));
        X.Mov(X.Div(
2));
    }

}


/****************************************************************************************
从字符串按2进制到36进制格式输入到大数
调用格式:N.Get(str,sys)
返回值:N被赋值为相应大数
***************************************************************************************
*/

void CBigInt::Get(CString& str, unsigned int system)
{
    
int len=str.GetLength(),k;
    Mov(
0);
    
for(int i=0;i<len;i++)
    
{
       Mov(Mul(system));
       
if((str[i]>='0')&&(str[i]<='9'))k=str[i]-48;
       
else if((str[i]>='A')&&(str[i]<='Z'))k=str[i]-55;
       
else if((str[i]>='a')&&(str[i]<='z'))k=str[i]-87;
       
else k=0;
       Mov(Add(k));
    }

}


/****************************************************************************************
将大数按2进制到36进制格式输出为字符串
调用格式:N.Put(str,sys)
返回值:无,参数str被赋值为N的sys进制字符串
***************************************************************************************
*/

void CBigInt::Put(CString& str, unsigned int system)
{
    
if((m_nLength==1)&&(m_ulValue[0]==0)){str="0";return;}
    str
="";
    
int a;
    
char ch;
    CBigInt X;
    X.Mov(
*this);
    
while(X.m_ulValue[X.m_nLength-1]>0)
    
{
        a
=X.Mod(system);
        ch
=CharTable[a];
        str.Insert(
0,ch);
        X.Mov(X.Div(system));
    }

}


/****************************************************************************************
求模逆,即解同余方程NX%A=1,亦即解不定方程NX-AY=1的最小整数解
调用方式:N.ModInv(A)
返回值:X,满足:NX%A=1
***************************************************************************************
*/

CBigInt CBigInt::ModInv(CBigInt
& A)
{
    CBigInt M,E,X,Y,I,J;
    
int x,y;
    M.Mov(A);
    E.Mov(
*this);
    X.Mov(
0);
    Y.Mov(
1);
    x
=y=1;
    
while((E.m_nLength!=1)||(E.m_ulValue[0]!=0))
    
{
         I.Mov(M.Div(E));
        J.Mov(M.Mod(E));
       M.Mov(E);
       E.Mov(J);
       J.Mov(Y);
       Y.Mov(Y.Mul(I));
       
if(x==y)
       
{
            
if(X.Cmp(Y)>=0)Y.Mov(X.Sub(Y));
            
else{Y.Mov(Y.Sub(X));y=0;}
       }

       
else{Y.Mov(X.Add(Y));x=1-x;y=1-y;}
       X.Mov(J);
    }

    
if(x==0)X.Mov(A.Sub(X));
    
return X;
}


/****************************************************************************************
求模乘
调用方式:N.ModMul(A,B)
返回值:X=N*A%B
***************************************************************************************
*/

CBigInt CBigInt::ModMul(CBigInt
& A, CBigInt& B)
{
    
int i,j;
    CBigInt X;
    X.Mov(A.Mul(m_ulValue[m_nLength
-1]));
    X.Mov(X.Mod(B));
    
for(i=m_nLength-2;i>=0;i--)
    
{          
        
for(j=X.m_nLength;j>0;j--)X.m_ulValue[j]=X.m_ulValue[j-1];
        X.m_ulValue[
0]=0;
        X.m_nLength
++;
        X.Mov(X.Add(A.Mul(m_ulValue[i])));
        X.Mov(X.Mod(B));
    }

    
return X;
}


/****************************************************************************************
求蒙哥马利模乘
调用方式:N.MonPro(A,B,n),(2**(k-1)<B<2**k,R=2**k,R*R'%B=1,n*B[0]%0x100000000=-1) 
返回值:X=N*A*R'%B
***************************************************************************************
*/

CBigInt CBigInt::MonPro(CBigInt
& A, CBigInt& B, unsigned long n)
{
    CBigInt X;
    unsigned 
long T[BI_MAXLEN*2];
    unsigned i,j,k;
    unsigned 
long m,carry;
    unsigned __int64 sum;
    
for(i=0;i<BI_MAXLEN*2;i++)T[i]=0;
    k
=B.m_nLength;
    
for(i=0;i<k;i++)
    
{
        carry
=0;
        
for(j=0;j<k;j++)
        
{
            sum
=A.m_ulValue[i];
            sum
=sum*m_ulValue[j]+T[i+j]+carry;
            T[i
+j]=(unsigned long)sum;
            carry
=(unsigned long)(sum>>32);
        }

        T[i
+k]=carry;
    }

    
for(i=0;i<k;i++)
    
{
       carry
=0;
       m
=T[i]*n;
       
for(j=0;j<k;j++)
       
{
           sum
=B.m_ulValue[j];
           sum
=sum*m+T[i+j]+carry;
           T[i
+j]=(unsigned long)sum;
           carry
=(unsigned long)(sum>>32);
       }

       
for(j=i+k;j<k*2;j++)
       
{
           sum
=T[j];
           sum
+=carry;
           T[j]
=(unsigned long)sum;
           carry
=(unsigned long)(sum>>32);
           
if(carry==0)break;
       }

    }

    T[k
*2]=carry;
    X.m_nLength
=k+1;
    
for(i=0;i<=k;i++)X.m_ulValue[i]=T[i+k];
    
while(X.m_ulValue[X.m_nLength-1]==0)X.m_nLength--;
    
if(X.Cmp(B)>=0)X.Mov(X.Sub(B));
    
return X;
}


/****************************************************************************************
求模幂
调用方式:N.ModExp(A,B)
返回值:X=N**A%B
***************************************************************************************
*/

CBigInt CBigInt::ModExp(CBigInt
& A, CBigInt& B)
{
    CBigInt X,Y;
    
int i,k;
    unsigned 
long n;
    k
=A.m_nLength*32-32;
    n
=A.m_ulValue[A.m_nLength-1];
    
while(n){n=n>>1;k++;}
    Y.m_nLength
=2;
    Y.m_ulValue[
1]=1;
    X.Mov(B.m_ulValue[
0]);
    X.Mov(X.ModInv(Y));
    X.Mov(Y.Sub(X));
    n
=X.m_ulValue[0];
    Y.Mov(
0);
    Y.m_nLength
=B.m_nLength+1;
    Y.m_ulValue[Y.m_nLength
-1]=1;
    X.Mov(Y.Sub(B));
    Y.Mov(ModMul(X,B));
    
for(i=k-1;i>=0;i--)
    
{
        X.Mov(X.MonPro(X,B,n));
        
if((A.m_ulValue[i>>5]>>(i&31))&1)X.Mov(X.MonPro(Y,B,n));
    }

    Y.Mov(
1);
    X.Mov(X.MonPro(Y,B,n));
    
return X;
}


/****************************************************************************************
测试素数
调用方式:N.TestPrime()
返回值:若N为素数,返回0,否则返回最小质因数,若质因数不可知,返回1
***************************************************************************************
*/

int CBigInt::TestPrime()
{
    unsigned i,pass;
    
if((m_ulValue[0]&1)==0)return 2;
    
for(i=0;i<1230;i++){if(Mod(PrimeTable[i])==0)return PrimeTable[i];}
    
if((m_nLength==1)&&(m_ulValue[0]<100180081))return 0;
    CBigInt S,A,I,K;
    K.Mov(
*this);
    K.m_ulValue[
0]--;
    
for(i=0;i<5;i++)
    
{
        pass
=0;
        A.Mov(rand());
        S.Mov(K);
        
while((S.m_ulValue[0]&1)==0)
        
{
            S.Mov(S.Div(
2));
             I.Mov(A.ModExp(S,
*this));
            
if(I.Cmp(K)==0){pass=1;break;}
        }

        
if((I.m_nLength==1)&&(I.m_ulValue[0]==1))pass=1;
        
if(pass==0)return 1;
    }

    
return 0;
}


/****************************************************************************************
产生随机素数
调用方法:N.FindPrime(bits)
返回值:N被赋值为一个bits位(0x100000000进制长度)的素数
***************************************************************************************
*/

void CBigInt::FindPrime(int bits)
{
    unsigned i;
    m_nLength
=bits;
    
for(i=1;i<m_nLength;i++)m_ulValue[i]=rand()*0x10000+rand();
    m_ulValue[m_nLength
-1]=m_ulValue[m_nLength-1]|0x80000000;

begin:
    m_ulValue[
0]=rand()*0x10000+rand();
    m_ulValue[
0]=m_ulValue[0]|3;
    
for(i=0;i<500;i++){if(Mod(PrimeTable[i])==0)goto begin;}
    CBigInt S,A;
    S.Mov(
*this);
    S.m_ulValue[
0]--;
    
for(i=0;i<S.m_nLength;i++)
    
{
        S.m_ulValue[i]
=S.m_ulValue[i]>>1;
        
if(S.m_ulValue[i+1]&1)S.m_ulValue[i]=S.m_ulValue[i]|0x80000000;
    }

    
if(S.m_ulValue[S.m_nLength-1]==0)S.m_nLength--;
    
for(i=0;i<5;i++)
    
{
        A.Mov(rand());
        A.Mov(A.ModExp(S,
*this));
        A.m_ulValue[
0]++;
        
if(((A.m_nLength!=1)||(A.m_ulValue[0]!=2))&&(Cmp(A)!=0))goto begin;
    }

}


发表于 @ 2007年11月25日 13:51:00 | 评论( loading... ) | 编辑| 举报| 收藏

旧一篇:ArcObjects二次开发的license验证问题 | 新一篇:在窗口控件上进行OpenGL绘图的方法

  • 发表评论
  • 评论内容:
  •  
Copyright © Cacar
Powered by CSDN Blog