概念:
Miller-Rabin 算法常用来判断一个大整数是否是素数,如果该算法判定一个数是合数,则这个数肯定是合数。Miller-Rabin 算法是一个概率算法,也就是说,若该算法判定一个大整数是素数,则该整数不是素数的概率很小。
Miller-Rabin 概率检测算法的理论基础是费马小定理,即设 n 是正奇整数,如果 n 是素数,则对于任意整数 b(1 < b < n-1),有 b^(n-1)≡1(mod n)。该命题的逆命题为:若 b^(n-1)≡1(mod n) 不成立,则n是合数。但该命题的逆命题并不一定成立。即若 b^(n-1)≡1(mod n),n 可能是素数,也可能是合数。
简单来说,如果对整数b(1 < b < n-1),(n, b)= 1,使得 b^(n-1)≡1(mod n) 不成立,则 n 是合数,如果成立,则 n 可能是素数,也可能是合数,需要通过再找别的整数b(1 < b < n-1),进行判断,只要有一种b不成立则为合数(注意可能两个字)。
代码实现:
# -*- coding:UTF-8 -*-
# Miller-Rabin素数检测算法
import math
def relatively_prime(a,b): # a > b
while b != 0:
temp = b
b = a%b
a = temp
if a==1:
return True
else:
return False
def millerRabin(num):
if num%2 ==0:
return False
flag = True
Subsquare = 0
temp = num - 1
while True:
temp = temp / 2
Subsquare += 1
if temp % 2 != 0:
break
b=[] # 存放所求整数(num)的原根
count = 0
for i in range(2,num-1):# g^(P-1) = 1 (mod P)
if relatively_prime(num,i):
b.append(i)
count += 1
if count == 5: # 控制检测次数
break
for i in b:
two = 0
while True:
if (i**temp)**(2**two)%num == 1 or (i**temp)**(2**two)%num == num-1:
flag = True
break
else:
two += 1
if two == Subsquare:
flag = False
break
if flag == False:
break # 如果存在一次不满足条件,则退出循环
return flag
num = input(u"请输入要进行Miller-Rabin算法检测的数:")
if millerRabin(num):
print u"{0}大概率是素数".format(num)
else:
print u"{0}是合数 ".format(num)