确定一个数字是否为素数的好算法?

时间:2010-09-07 14:04:19

标签: algorithm primes

  

可能重复:
  Checking if an int is prime more efficiently

我需要测试一些非常大的整数来查看它是否是素数。你能提供一些好的算法或库例程吗?

编辑:C / C ++没问题。

感谢。

2 个答案:

答案 0 :(得分:6)

Miller-Rabin test非常快,对某些数字范围来说既快又确定。

答案 1 :(得分:0)

最简单的选择是使用现有的大整数库。它不会有错误,它将提供所有支持功能。

如果您正在编写自己的实现(即作业),我建议您使用书中的伪代码算法,以便了解自己在做什么。

话虽这么说,最简单的方法之一是使用Jacobi和Legendre,并比较相等。我刚刚提交了RSA加密的作业。这是我对单精度所做的,但算法是通用的,也适用于多个精度整数。

typedef uint64_t BigIntT;
typedef int64_t SBigIntT;

// This function calculations the power of b^e mod phi
// As long as 
//      b*b is smaller than max(BigIntT) 
//      b*phi is smaller than max(BigIntT)
// we will not have overflow.
BigIntT calculatePower (BigIntT b, BigIntT e, BigIntT m) {
    BigIntT result = 1;

    while (e != 0) {
        if (e & 1) {
            result = (result * b) % m;
        }

        e = e >> 1;
        b = (b * b) % m;
    }

    return result;
}

// This function implements simple jacobi test.
// We can expect compiler to perform tail-call optimisation.
SBigIntT jacobi (SBigIntT a, SBigIntT b) {
    if (a == 0 || a == 1) {
        return a;
    } else if (a % 2 == 0) {
        if (((b*b - 1) / 8) % 2 == 0) {
            return jacobi(a/2, b);
        } else {
            return -jacobi(a/2, b);
        }
    } else if ((((a-1) * (b-1)) / 4) % 2 == 0) {
        return jacobi(b % a, a);
    } else {
        return -jacobi(b % a, a);
    }
}

// This function implements : http://en.wikipedia.org/wiki/Solovay-Strassen_primality_test
bool testPrime (BigIntT p) {
    int tests = 10;

    if (p == 2) {
        return true;
    }

    while (tests-- > 0) {
        BigIntT a = generateRandomNumber(2, p);

        if (greatestCommonDivisor(a, p) == 1) {
            BigIntT l = calculatePower(a, (p-1)/2, p);
            SBigIntT j = jacobi(a, p);

            // j % p == l
            if ((j == -1) && (l == p-1) || (j == l)) {
                // So far so good...
            } else {
                // p is composite
                return false;
            }
        } else {
            // p is composite
            return false;
        }
    }

    return true;
}