实施费马的素性测试

时间:2010-10-26 19:22:40

标签: java math primes biginteger

谁想帮我做作业?

我尝试使用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 个答案:

答案 0 :(得分:2)

您对特定BigInteger构造函数的使用是合理的,但您应该使用rejection method来选择fermat base 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));
    }
}

答案 1 :(得分:1)

a应该是“在范围内随机选择(1,n - 1)”并且我并没有真正看到这种情况。你可以打印一个来检查它。

至于如何做到这一点:

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

e.g。您不应该将BigInteger构造函数与Random参数一起使用;这只是随机性的来源,但 a 应该是一个随机

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