【问题标题】:Implementation of Fermat's primality test费马素数检验的实现
【发布时间】:2011-04-30 22:40:55
【问题描述】:

谁愿意帮我做作业?

我正在尝试使用 BigIntegers 在 Java 中实现 Fermat's primality test。我的实现如下,但不幸的是它不起作用。有什么想法吗?

public static boolean checkPrime(BigInteger n, int maxIterations)
{
    if (n.equals(BigInteger.ONE))
        return false;

    BigInteger a;
    Random rand = new Random();

    for (int i = 0; i < maxIterations; i++)
    {
        a = new BigInteger(n.bitLength() - 1, rand);
        a = a.modPow(n.subtract(BigInteger.ONE), n);

        if (!a.equals(BigInteger.ONE))
            return false;
    }

    return true;
}

我是 BigIntegers 的新手。

谢谢!

【问题讨论】:

  • 如果你能说出“不起作用”的样子,你会有更好的运气。
  • “不起作用”是指它没有给出正确的结果。例如,当我针对 2、3、5 和 7 等素数测试它时,它应该返回“true”时返回“false”。
  • 你检查过 a = new BigInteger(n.bitLength() - 1, rand);确实是打印时的正常值,并且 rand 从 1 正确初始化为 n (我没有看到那部分)?

标签: java math primes biginteger


【解决方案1】:

您使用特定的 BigInteger 构造函数是合理的,但您应该使用rejection method 来选择基数 a。这是对您的方法在一个类中的轻微修改,该类也只使用一个 Random 对象:

import java.math.BigInteger;
import java.util.Random;

public class FermatTestExample
{

    private final static Random rand = new Random();

    private static BigInteger getRandomFermatBase(BigInteger n)
    {
        // Rejection method: ask for a random integer but reject it if it isn't
        // in the acceptable set.

        while (true)
        {
            final BigInteger a = new BigInteger (n.bitLength(), rand);
            // must have 1 <= a < n
            if (BigInteger.ONE.compareTo(a) <= 0 && a.compareTo(n) < 0)
            {
                return a;
            }
        }
    }

    public static boolean checkPrime(BigInteger n, int maxIterations)
    {
        if (n.equals(BigInteger.ONE))
            return false;

        for (int i = 0; i < maxIterations; i++)
        {
            BigInteger a = getRandomFermatBase(n);
            a = a.modPow(n.subtract(BigInteger.ONE), n);

            if (!a.equals(BigInteger.ONE))
                return false;
        }

        return true;
    }

    public static void main(String[] args)
    {
        System.out.printf("checkprime(2) is %b%n", checkPrime(BigInteger.valueOf(2L), 20));
        System.out.printf("checkprime(5) is %b%n", checkPrime(BigInteger.valueOf(5L), 20));
        System.out.printf("checkprime(7) is %b%n", checkPrime(BigInteger.valueOf(7L), 20));
        System.out.printf("checkprime(9) is %b%n", checkPrime(BigInteger.valueOf(9L), 20));
    }
}

【讨论】:

    【解决方案2】:

    a 应该是“在 (1, n − 1] 范围内随机选择 a)”,但我并没有真正看到这种情况发生。您可以打印 a 来检查。

    至于怎么做:

    BigInteger a = BigInteger.valueOf(random.nextInt(n-2)+2);
    

    例如您不应该使用带有 Random 参数的 BigInteger 构造函数;这只是随机性的来源,但 a 应该是随机的

    'random.nextInt(n-1)+1' 来自 nextInt 的定义,给定参数 k,返回一个随机值 0,直到并包括 k-1。并且您希望 a 大于 1 且小于 n。

    【讨论】:

    • 好点——我认为这就是问题所在。但是,如何将范围应用于 Java 中的 Random 对象?
    • @DT3 您在简单、明显的问题上获得最多分。很多人对此都有答案并阅读了您的答案。
    • 这个答案假定 n 是一个 int,它不是。
    • 我急于将问题标记为已回答。正如 GregS 所说,问题在于“n”是 BigInteger,而不是 int。
    猜你喜欢
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    相关资源
    最近更新 更多