大整数素性测试

源代码:

typedef long int HugeInt;
 
HugeInt Witness(HugeInt A, HugeInt i, HugeInt N)
{
	HugeInt X, Y;
	
	if(i == 0)
		return 1;
	
	X = Witness(A, i/2, N);
	if(X == 0)
		return 0;
	
	Y = ( X * X) % N;
	if(Y == 1 && X !=1 && X != N-1)
		return 0;
	
	if(i % 2 != 0)
		Y = (A * Y) % N;
	
	return Y;
}

bool IsPrime(HugeInt N)
{
	return Witness(RandInt(2, N-2), N - 1, N) == 1;
}

原理:

        1.  费马小定理:如果N是素数,且0 < A < N,那么A^(N-1)  mod N = 1

             由上述定理可知,如果A^(N-1)  mod N != 1,则N为非素数。

             但是如果A^(N-1)  mod N = 1,我们不能推导出N为素数。

             例如:N=341,但满足上述公式,但341为非素数。

                         A=3, N = 561, 满足上式,但561非素数。由此可见,不恰当的A也可能导致算法出错。

         

        2. 定理:如果N是素数,且0 < X < N,那么X^2 mod N = 1仅有的两个解为X=1, X = N-1。

            证明: X^2 - 1 mod N = 0

                         (X+1)(X-1) mod N = 0

                         由于N是素数,只有因子1与N,所以N要么整除X+1,要么整除X-1。因为0 < X < N,所以X=1或者X=N-1时有解。

             因此,如果X^2 mod N = 1时,X不为1或者N-1,则说明N为非素数。


         3. 总结:使用定理1来验证一个大数是否为素数(A^(N-1)  mod N = 1),为了减少误差,在计算的时候使用定理2进行测试,如果

                          出现不满足情况,则终止测试,返回非素数。

                          但这样并只能减少误差,不能消除错误,所以,可以通过独立随机试验减少错误发生概率。

                          试验证明,如果随机选取A,该算法有75%的正确率,即错误率为25%。这样,如果我们进行50次试验,误差不大于1/4^50。

                         

代码:

         1. 本算法用到了递归求幂算法

         2. 定理2的运用          

Y = ( X * X) % N;
if(Y == 1 && X !=1 && X != N-1)
    return 0;

             当X^2 mod N = 1时,X !=1 或X!=N-1,则说明该数为非素数,检查可以终止。

         3. 递归求幂 幂为奇数

if(i % 2 != 0)
    Y = (A * Y) % N

             当幂为奇数的时候,要多乘一次A

         4. 实质是递归求幂的反过程  

if(i == 0)
    return 1;

Witness(A, i/2, N);

Y = ( X * X);if(i % 2 != 0) Y = (A * Y);
    return Y;

               只看上述代码,其实就是递归求幂的过程。 

          5. 费马小定理

              Witness求A^(N-1)  mod N。如果返回值为1,则以很大的概率认为该数为素数。

          6. %N的作用

              (x * y) % N = (    (x % N)  *  ( y % N)   )  % N

              所以,在各个阶段计算的过程中取余,对最终的结果是没有影响的。即如果A^(N-1)  mod N = 1,那么用各个计算

              的中间结果去mod N,对最终结果是没有影响的。

              而同时Y = ( X * X) % N计算,正好方便了定理2的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值