1. 程式人生 > >Python Miller-Rabin素性檢測演算法

Python Miller-Rabin素性檢測演算法

概念:

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)