📅  最后修改于: 2023-12-03 14:55:46.577000             🧑  作者: Mango
在数字论中,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素性测试是用来检测质数的更完整的算法。它的算法复杂度是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
经过费马小定理和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伪素数。