说实话,费马质数测试是有点坑的,并不能保证这个数真的是一个质数。费马质数测试的理论依据是费马小定理Fermat’s little theorem。费马小定理的内容是,对于一个质数p,和一个与他互质的数a,有下列关系:
a
p
−
1
≡
1
m
o
d
p
a^{p-1}\equiv 1\;mod\;p
ap−1≡1modp
好消息是大部分合数都不能通过费马测试,只有少数合数能通过费马测试,这类数叫做卡迈克尔数Carmichael numbers,比如
3
∗
11
∗
17
=
561
3*11*17=561
3∗11∗17=561就是个卡迈克尔数。至于指数,可以用二进制快速幂计算指数。
在编程中,一般是随机选择五个数字进行费马测试。如果通过了就认为这个数字很大可能为质数。
以下是python实现:
# _*_ coding:utf-8 _*_
import random
def binary_exponentiation(base, power):
power_2 = 1
r = 1
p = base
while (power_2 := power_2 << 1) <= power:
p = p * p
if power_2 & power != 0:
r *= p
return r
def is_prim(n):
if n <= 4:
return n == 2 or n == 3
for i in range(5):
a = random.randint(2, n)
r = binary_exponentiation(a, (n - 1)) % n
if r != 1:
return False
return True
if __name__ == '__main__':
print(is_prim(10000))
print(is_prim(911))
print(is_prim(561))
print(is_prim(341))
我这四个数字的测试结果是:
False
True
True
False
341是不能通过费马小定理测试的。但是我在某度百科看到了这样一个结论:
希望大家擦亮眼睛,自己多写写代码去验证,毕竟权威也是会出错的。