【问题标题】:Miller-Rabin Primality test in JavaJava 中的 Miller-Rabin 素性测试
【发布时间】:2013-06-09 11:02:59
【问题描述】:

我目前正在研究Project Euler,并认为如果不只是蛮力解决所有问题,它可能会更有趣(以及更好的学习体验)。在问题 3 中,它要求一个数的素因数,我的解决方案是对数进行因式分解(使用另一种因式分解算法),然后测试这些因数的素数。我为米勒-拉宾素性测试提出了这段代码(在彻底研究素性测试之后),它对我输入的所有复合奇数返回 true。有人能帮我找出原因吗?我以为我已经正确编码了算法。

    public static boolean isPrime(long num)
{
if(num % 2 == 0)
    return false;
else
{
    double d;
    int r=0;
    while((num-1) % Math.pow(2,r+1) == 0)
        r++;
    d = (num-1) % Math.pow(2,r);
    int[] a = {2,3,5,7,11,13,17,23,31,62,73,1662803};
    boolean primality = true;
    for(int k = 0; k < a.length; k++)
    {
        if((Math.pow(a[k],d)-1) % num != 0)
        {
            for(int s = 0; s < r-1; s++)
            {
                if((Math.pow(a[k],Math.pow(2,s)*d)+1) % num != 0)
                    primality = false;

            }
        }
    }
    return primality;
}

【问题讨论】:

  • 你试过追踪代码吗?
  • 这与您的代码无关,我也没有多少专业知识,但是“分解数字(使用另一种分解算法)”是一个比识别素数更难的问题。您可以通过获取素数列表来避免强制分解。获取素数列表(与测试素数相对应)的最简单方法是使用筛子。
  • @JanDvorak:提出了一个很好的观点。您应该考虑用 BigInteger 类替换 long 的使用。
  • @JuanSebastianLozanoMuñoz:22?这听起来很奇怪。我希望第一个 if 条件能够捕捉到这一点。你确定你调用的是正确的函数吗?
  • 不应该 while(num % Math.pow(2,r+1) == 0)while((num-1) % Math.pow(2,r+1) == 0) 或者更好(对我来说)while((num-1) % (1&lt;&lt;r+1) == 0) 然后是 d = ((num-1) % (1&lt;&lt;r));

标签: java primes number-theory


【解决方案1】:

给定num &gt; 3,你想要:d, r s.t. pow(2,r) * d = num - 1, where d is odd

您实际上是在计算 num - 1 的尾随零,以删除 2 的因子。然而,在那个循环之后,你知道pow(2,r)num - 1 的一个因子。因此:

d = (num-1) % Math.pow(2,r);

将始终产生:d = 0。我怀疑您打算在这里用/ (div) 替换% (mod);否则,Math.pow(a[k],d)-1 将始终产生 (0),并且永远不会执行内部循环。

正如其他人指出的那样,一些简单的跟踪语句或断言会发现这些错误。我认为您还有其他问题,例如整数溢出。测试a[] 候选者的循环(a-SPRP 测试)在我看来完全错误。

也许你从Wikipedia 得到了算法,我更喜欢The Handbook of Applied Cryptography 中更详细的参考:4.2.3: Miller-Rabin test, Algorithm: 4.24

【讨论】:

  • 感谢您提供的信息丰富的回答 :) 我会查看您提供的资源,因为它们看起来非常有用,下次使用跟踪语句时会更加小心(现在我知道那些是)。
  • @JuanSebastianLozanoMuñoz - 由于您正在处理 Project Euler 问题,我想您可能会发现高效的 Miller-Rabin 测试很有用,所以我为您准备了 sn-p here
  • 哇,非常感谢 :) 这肯定会帮助我解决 PE 问题。
猜你喜欢
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
相关资源
最近更新 更多