`
xinklabi
  • 浏览: 1587736 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

用BigInteger实现大素数生成算法

 
阅读更多

转自:http://www.cnblogs.com/edwardstudy/archive/2012/11/24/2784174.html

一.通过素数的基本性质

  根据素数的性质(除了1和此整数(n)自身外,无法被其他自然数整除的数):即从2到n/2的数都不能整除n。

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

  用大于2^63的数去测试,结果因为运算量太大,运行半个来小时也没有结果出现。

二.通过素数表

  要提高速度就要减少进入判断方法中的循环:

  1.偶数可以排除

  2.大的合数(即素数的积)可以排除

  排除偶数直接增加一个判断即可实现,而排除大的合数也通过产生一个素数表实现。

  这里引援51CTO网友 梦朝思夕 BOLG,即“一般来说整除100 以内的所有素数可排除76% 不是素数的可能性 整除256以内的所有素数可排除80% 不是素数的可能性。” 而我同样地建大小为2000的表,private static BigInteger[] primeList = new BigInteger[2000]

primeList[1999] = 17389

复制代码
for(int i = 0, j = 2; i < 2000; j++)
{
    if(isPrime(j))
    {
        primeList[i] = BigInteger.valueOf(j);
        i++;
    }
}
复制代码

  再来一个方法判断新生成的大数判断是否为几个素数的积

复制代码
public static boolean isNotPrimeProduct(BigInteger num)
{
    for(int i=0;i< 2000; i++)
    {
          if(num.remainder(primeList[i]) == BigInteger.ZERO)
          {
                return false;
           }
         }
        
       return true;
}
复制代码

素数表太大也减慢速度,而且数值越大,素数表判别的确定性就越小。要知道,我们要的是2^63。

 

三.通过费马(Fermat)素数检验

  在网上查阅资料,知道可以运用费马小定理检验一个数是否不是合数。

 费马小定理是数论中的一个定理:假如a是一个整数,p是一个质数,那么
<iframe id="iframe_0.12259612022899091" style="margin: 0px; padding: 0px; border-style: none; border-width: initial; width: 669px;" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload.wikimedia.org/math/9/3/2/932d312464b299b86f5e760c1ad0d1ec.png?_=2784174%22%20style=%22border:none;max-width:669px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.12259612022899091',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>

如果a不是p的倍数,这个定理也可以写成

<iframe id="iframe_0.5152008500881493" style="margin: 0px; padding: 0px; border-style: none; border-width: initial; width: 669px;" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload.wikimedia.org/math/6/5/a/65a9d7295e7bd6db0a8ec7b6cd74ae58.png?_=2784174%22%20style=%22border:none;max-width:669px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.5152008500881493',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>

                                                                    来自wiki

 根据费马小定理:如果p是素数,<iframe id="iframe_0.04923537909053266" style="margin: 0px; padding: 0px; border-style: none; border-width: initial; width: 669px;" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload.wikimedia.org/math/2/5/3/253e404f0744634e128dadfacba12b53.png?_=2784174%22%20style=%22border:none;max-width:669px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.04923537909053266',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>,那么
<iframe id="iframe_0.6658551236614585" style="margin: 0px; padding: 0px; border-style: none; border-width: initial; width: 669px;" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload.wikimedia.org/math/6/5/a/65a9d7295e7bd6db0a8ec7b6cd74ae58.png?_=2784174%22%20style=%22border:none;max-width:669px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6658551236614585',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>

如果我们想知道n是否是素数,我们在中间选取a,看看上面等式是否成立。如果对于数值a等式不成立,那么n是合数。如果有很多的a能够使等式成立,那么我们可以说n 可能是素数,或者伪素数。

在我们检验过程中,有可能我们选取的a都能让等式成立,然而n却是合数。这时等式

<iframe id="iframe_0.24898810521699488" style="margin: 0px; padding: 0px; border-style: none; border-width: initial; width: 669px;" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload.wikimedia.org/math/2/e/3/2e3402f60acea95ebfc5ea589fd95c61.png?_=2784174%22%20style=%22border:none;max-width:669px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.24898810521699488',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>

被称为Fermat liar。如果我们选取满足下面等式的a

<iframe id="iframe_0.25041508045978844" style="margin: 0px; padding: 0px; border-style: none; border-width: initial; width: 669px;" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload.wikimedia.org/math/4/f/5/4f5d7dbc502ef72888384995e396d2e2.png?_=2784174%22%20style=%22border:none;max-width:669px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.25041508045978844',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>

那么a也就是对于n的合数判定的Fermat witness

                                                                   来自wiki

  而在这里我从cnblogs的Knuth_档案学到了大量理论知识和算法的实现。(特别是蒙哥马利快速积模算法:计算大数(x^y)%z)

  用java实现如下

复制代码
public static BigInteger Montgomery(BigInteger n, BigInteger p, BigInteger m)
    {
        n = n.remainder(m) ;
        BigInteger k = BigInteger.ONE;
        while(p.compareTo(BigInteger.ONE) == 0)
        {
            if(!(p.remainder(BigInteger.ONE) == BigInteger.ZERO))
            {
                k = (k.multiply(n)).remainder(m);
            }
            n = (n.multiply(n)).remainder(m);
            p = p.divide(BigInteger.valueOf(2));
        }
        
        return (n.multiply(k)).remainder(m);
    }
复制代码

 

  接下来,我们就可以对一个大数使用费马素数检验可以判定这个大数是伪素数。

  从前2000素数一一检验,而费马素数检验只是随机化了。

复制代码
public static boolean fermatPrimalityTest(BigInteger num)
    {
        for(int i = 0; i < 2000; i++)
        {
            if(!(Montgomery(primeList[i], num.subtract(BigInteger.ONE), num).compareTo(BigInteger.ONE) == 1))  //(x^y)%z
            {
                return false;
            }
        }
        
        return true;
    }
复制代码

 

 

使用素数表的前十个结果:

9223372036854775809
9223372036854775811
9223372036854775813
9223372036854775815
9223372036854775817
9223372036854775819
9223372036854775821
9223372036854775823
9223372036854775825
9223372036854775827

使用费马素数检验过的前十个结果:

9223372036854775817
9223372036854775837
9223372036854775889
9223372036854775903
9223372036854775907
9223372036854775931
9223372036854775937
9223372036854775939
9223372036854775949
9223372036854775963

四.总结

  现在我们可以通过结果简单的分析出出只是使用素数表的结果有很多都通不过费马素数检验,因为素数表总有上界。最后可以通过Knuth所说的 拉宾米勒测试排除掉那些卡尔麦克(Carmichael)数。

 

分享到:
评论

相关推荐

    密码学大素数生成

    Java实现大素数生成 在Java中,我们可以使用BigInteger类来生成大素数。BigInteger类提供了许多有用的方法,可以用于生成和操作大素数。下面是一个简单的示例代码: ```java import java.math.BigInteger; public...

    RSA.rar_BigInteger_RSA BigInteger_RSA java biginteger_RSA 类 java

    在Java中,我们可以使用`java.math.BigInteger`类来处理大整数,这在实现RSA算法时非常关键,因为加密过程中涉及的数字通常超过了普通整型变量的范围。以下是关于`BigInteger`类以及如何在Java中实现RSA加解密的详细...

    RAS算法Java实现.pdf

    4. Java实现:RAS算法的Java实现使用BigInteger类来表示大整数,并使用Random类来生成随机数。 代码解释 1. static BigInteger p,q,e,q1,p1,p2,q2,e1,m;:定义了RAS算法中的变量,包括两个大素数p和q,公钥e,私钥d...

    BigInteger_src.zip

    在C#编程中,通常会使用.NET Framework提供的System.Numerics.BigInteger类来处理大整数运算,这是RSA算法的基础。BigInteger类允许我们进行任意大小的整数操作,包括乘法、除法、加法、减法以及模幂运算等,这些都...

    用JAVA语言实现RSA公钥密码算法.pdf

    为了生成RSA算法所需的两个大素数(\(p\) 和 \(q\)),需要使用高质量的随机数生成器。 - **素性检测**:并非所有的随机数都是素数,因此需要一种有效的机制来判断一个给定的数是否为素数。常用的素性检测方法包括...

    大数计算器(支持大素数判定)

    在IT领域,大数计算器是一种专门处理超过常规计算范围的大整数的工具。"大数计算器(支持大素数判定)"这样的程序尤其在...它的四则运算、快速幂取模和随机大素数生成等功能,都是为了满足这些领域的特定需求而设计的。

    C#RSA私钥加密公钥解密

    在这个特定的案例中,`MyRSA.cs` 文件提供了一个实现,它使用了 `System.Numerics.BigInteger` 类来处理大整数,这是RSA算法的关键部分。 `System.Numerics.BigInteger` 是.NET框架中的一个类,它支持任意大小的...

    RSA算法的JAVA实现

    1. **选择大素数**:在JAVA中可以通过随机数生成器和素数检测算法来选择两个足够大的素数\( p \)和\( q \)。 2. **密钥生成**: - 使用BigInteger类来处理大整数运算。 - 实现Euler函数来计算\( \phi(n) \)。 - ...

    RSA算法C++实现

    - 性能:RSA加密和解密速度相对较慢,适合用于少量数据的加密,大量数据通常使用RSA进行小部分数据的交换,然后用对称加密算法处理大部分数据。 - 密钥长度:为了保证安全性,密钥长度至少应为2048位,更长的密钥...

    用java编程实现算法

    本文详细介绍了如何使用Java编程语言实现RSA算法的过程,包括密钥对的生成、扩展欧几里得算法以及加密模块的设计与实现。通过上述方法,可以有效地保护网络通信中的数据安全。需要注意的是,实际应用中还需要考虑更...

    Diffie_Hellman算法的C#实现

    在C#中实现Diffie-Hellman算法,首先需要一个大数运算库,因为涉及到大整数的加减乘除以及指数模运算。在.NET框架中,`System.Numerics.BigInteger`类提供了对大数的支持,可以用来实现这些基本操作。此外,还需要...

    C#实现RSA加密算法

    标题提到的"C#实现RSA加密算法"着重讲述了如何在C#中利用大整数类BigInteger和RSACryptoServiceProvider类来完成私钥加密公钥解密的过程。以下是对这个话题的详细解释: 1. **RSA算法基础**: RSA算法由Rivest、...

    RSA实现算法报告关于RSA算法的实现代码

    - 实现思路:利用Java语言中的`java.math.BigInteger`类生成随机大数。 **判断素数的方法**: - 方法名称:`MillerRobin(BigInteger num)` - 实现思路:采用Miller-Rabin素性测试算法,这是一种概率性算法,用于...

    BigInteger:为Java实现BigInteger

    在Java编程语言中,`BigInteger`类是用于处理大整数的一种重要工具。它属于`java.math`包,专门设计来处理超过`long`类型所能表示的最大范围的整数。当我们需要进行大整数的算术运算,如加法、减法、乘法、除法以及...

    java:判断一个数是否为素数的函数

    优化之后的算法可以显著提高效率,特别是在需要判断大量大整数是否为素数时。在Java中,还可以利用一些现成的算法库,如Apache Commons Math或者Java自身的BigInteger类的isProbablePrime方法来判断一个大数是否为...

    RAS算法Java实现

    在Java中,可以使用大整数的幂运算`modPow`方法实现。 6. **解密过程**:解密过程为m ≡ c^d (mod n),恢复原文。同样,这个操作也可以用`modPow`方法完成。 7. **测试和验证**:`testsu`方法用于测试一个整数是否...

    电子商务中常用的RSA算法实现.docx

     使用Java中的BigInteger类来实现RSA算法。  生成公钥/私钥对,用户输入一串字符串,用公钥加密字符串,用私钥解密字符串,所有的结果被输出。 3.主要算法流程:  随机生成p,q→计算N=p*q→计算p1=p-1,q1=q-1→...

    java实现RSA算法

    Java提供了强大的`java.math.BigInteger`类来处理大整数运算,这对于RSA算法的实现至关重要,因为RSA算法涉及到的大数运算超出了常规数据类型所能表示的范围。此外,`java.util.Random`类用于生成随机数,这是选择...

    基于C语言的RSA算法高效实现

    RSA算法的安全性基于大整数因子分解的困难性,所以在密钥生成时,尽量要求n很大,这样攻击者要成功地分解为φ(n)=(p-1)·(q-1)非常困难,从而保证了攻击者即使知道了pk={n,e}也不能通过d≡e-1mod(n)推导...

Global site tag (gtag.js) - Google Analytics