素数

1. 素数的判定

方法1:1到 蛮力测试

//素数的判定

//2 到sqrt(x) 整除x,只要有一个能除尽,说明x 不是素数

BOOL isPrime1(UINT32 x)

{

     switch(x)

     {

     case 0:

         return FALSE;

     case 1:

         return FALSE;

     case 2:

         return TRUE;

     case 3:

         return TRUE;

     default:

         break;

     }

     //以上是处理边界情况1 2 3

 

     for(UINT32 i = 2; i <= static_cast<UINT32>(sqrt(static_cast<float>(x)));

         ++i)

     {

         if(0U == x % i)

         {

              return FALSE;

         }

     }

     return TRUE;

}

 

方法2:用素数表测试

//素数的判定

//如果x 不是太大,素数表的最大素数是不小于sqrt(x)的最大素数,用素数表的每个素数

//去整除x,只要有一个能整除,说明x是合数,返回FALSE;

//只有小于sqrt(x)内的所有素数都不能整除x,说明x是素数,返回TRUE

UINT32 list[] = {2,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};//sqrt(10000)内的素数表

BOOL isPrime2(UINT32 x)

{

     switch(x)

     {

     case 0:

         return FALSE;

     case 1:

         return FALSE;

     case 2:

         return TRUE;

     case 3:

         return TRUE;

     default:

         break;

     }

     //以上是处理边界情况1 2 3

 

     UINT32 i = 0;

     while(list[i] * list[i] <= x)

     {

         if(0 == x % list[i])

         {

              return FALSE;

         }

         ++i;

     }

     return TRUE;

}

方法3:米勒-拉宾测试

    令大奇数n= m+1,其中l是非负整数,m是正奇数,若 1( )或 -1( ), ,则称n通过b为基的米勒-拉宾测试。

定理 如果n是奇合数,0<b<n,则使n通过Miller-Rabin测试的b的个数不超过 (n-1)(即n通过b的Miller-Rabin测试的概率最高是 )。

    例如随机选取n,通过依次随机取 的Miller-Rabin测试,n是合数的概率不超过 = =0.00000095,至少以0.999999的概率判定n是素数。

定理简单明了,但证明却需要许多准备。

//米勒-拉宾测试

//n=2^m*l+1

BOOL passMillerRabinTest(UINT32 n)

{

     UINT 32 l = 0U;

     UINT 32 m = n - 1;

     while(0U == m % 2U)

     {

         l += 1;

         m /= 2U;

     }

 

     UINT32 b = rand() % (n - 1U) + 1;

     if(1U == modExp(b, m, n))

     {

         return TRUE;

     }

     UINT32 j = m;

     for(UINT32 i = 0U; i < l; ++i)

     {

         if(modExp(b, j, n) == n - 1)

         {

              return TRUE;

         }

         j *= 2;

     }

 

     return FALSE;

}

2. 产生一个素数

       在实际应用中,经常需要大素数,产生大素数的过程如下:

1)产生一个n位随机数pn位二进制);

2)将最高位和最低为置为1(最高位置1保证了产生的素数足够大,而最低位为1保证为奇数);

3)检查p是否能被小素数整除:35711等。许多实际应用中都用小于256的所有素数去除p

4)对于随机数a,进行Miller-Rabin测试,如果p通过了,则产生另一个随机数a再进行测试。选择值小一些的额a可以令计算更快。做5次测试,只要p没有通过其中的一次,转(1)重新开始;

       另一种方法不是每次产生一个随机数,而是从一个起始数开始逐次递增,直到找到素数。

       步骤(3)是可选的,但很有用。测试一个随机奇数p是否能被357整除,可以在第(4)步测试前去掉54%的基数,用100以内的素数测试可以去掉76%的奇数,而用256以内的素数测试可以去掉80%的奇数。一般地,奇数中不为任何小于n的素数的倍数的数的比例占1.12/lnn

查看原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值