📜  检查数字是否为Fermat伪素数(1)

📅  最后修改于: 2023-12-03 14:55:46.577000             🧑  作者: Mango

检查数字是否为Fermat伪素数

在数字论中,Fermat伪素数是一类漏洞行为的合数,它可以通过费马小定理轻松地通过素性测试,但不实际是素数。因此,需要额外的测试来排除Fermat伪素数。

Fermat小定理

费马小定理是素性测试中最基本的公式之一。在其他检查之前,我们需要先检查数字是否通过费马小定理。

费马小定理的公式可以表示为:a^(p-1) ≡ 1 (mod p)

其中,a是一个整数,p是一个质数。如果数字n不能满足这个公式,则n一定不是质数。数字n通过公式的可能性非常高,因此我们不能仅仅依靠这个公式来检查质数。

def is_prime_fermat(n: int, k: int) -> bool:
    if n == 2:
        return True

    if not n & 1:
        return False

    for _ in range(k):
        a = random.randint(2, n - 1)
        if pow(a, n - 1, n) != 1:
            return False

    return True
Miller-Rabin素性测试

Miller-Rabin素性测试是用来检测质数的更完整的算法。它的算法复杂度是O(k log^3 n),其中k是迭代检查的次数。

Miller-Rabin测试是Fermat小定理的一种扩展,可以检查比费马小定理更多的数字。

def is_prime_miller_rabin(n: int, k: int) -> bool:
    if n == 2 or n == 3:
        return True

    if n <= 1 or not n & 1:
        return False

    def check(a, s, d, n):
        x = pow(a, d, n)
        if x == 1:
            return True

        for i in range(s - 1):
            if x == n - 1:
                return True
            x = pow(x, 2, n)
        return x == n - 1

    s = 0
    d = n - 1
    while not d & 1:
        d >>= 1
        s += 1

    for _ in range(k):
        a = random.randint(2, n - 1)
        if not check(a, s, d, n):
            return False

    return True
Fermat伪素数检测

经过费马小定理和Miller-Rabin素性测试的检查之后,我们可以进行更全面的Fermat伪素数检测。

在这种方法中,我们首先检查数字n是否通过了费马小定理。如果n无法通过费马小定理,那么它一定不是质数。

然后,我们需要计算x对n的平方进行循环,直到n-1没有余数。如果在此期间,我们得到了与n同样的余数,那么n可能是Fermat伪素数。如果我们通过所有循环,都没有得到与n相同的余数,则n一定是合数。

def is_pseudo_fermat(n: int) -> bool:
    if n < 3:
        return False

    a = 2
    while a < n:
        if pow(a, n-1, n) != 1:
            return False

        x = pow(a, 2, n)
        while x != 1 and x != n - 1:
            x = pow(x, 2, n)

        if x == n - 1:
            return False

        a += 1

    return True
总结

通过费马小定理和Miller-Rabin素性测试,我们可以排除所有负责和大部分Fermat伪素数。如果需要更全面的检查,我们可以使用Fermat伪素数检测。虽然这个方法的复杂度很高,但是在实际中不会检查所有整数,而仅仅是检查少数整数,因此可以使用此方法方便地检查Fermat伪素数。