这是我的代码:
from math import sqrt
def isPrime(value):
a = []
for i in range(1, int(sqrt(value)) + 1):
if value <= 3:
return value
if value % 2 == 0:
break
if value % i == 0:
a.append(i)
i += 1
continue
elif value % i != 0:
a = a
continue
if len(a) == 1:
return value
else:
pass
我希望能够使用它来测试大数字,但是尽可能快。
答案 0 :(得分:1)
import math
def initial_data(number):
count = 0
goree = number - 1
floor = number // 2
while goree % 2 == 0:
goree //= 2
count += 1
results = [floor, count]
return results
def test_values(num):
test_vals = []
if num < 2047:
test_vals = [2]
elif num < 1373653:
test_vals = [2, 3]
elif num < 9080191:
test_vals = [31, 73]
elif num < 25326001:
test_vals = [2, 3, 5]
elif num < 3215031751:
test_vals = [2, 3, 5, 7]
elif num < 4759123141:
test_vals = [2, 7, 61]
elif num < 1122004669633:
test_vals = [2, 13, 23, 1662803]
elif num < 2152302898747:
test_vals = [2, 3, 5, 7, 11]
elif num < 3474749660383:
test_vals = [2, 3, 5, 7, 11, 13]
elif num < 341550071728321:
test_vals = [2, 3, 5, 7, 11, 13, 17]
elif num < 3825123056546413051:
test_vals = [2, 3, 5, 7, 11, 13, 17, 19, 23]
elif num < 2**64:
test_vals = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
elif num < 318665857834031151167461:
test_vals = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
elif num < 3317044064679887385961981:
test_vals = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41]
return test_vals
def rabin_miller(num):
base_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229, 233, 239,241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,
317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449,
457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521,523, 541, 547, 557, 563, 569, 571, 577, 587,
593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661,673, 677, 683, 691, 701, 709,
719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853,
857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991,
997]
if num <= 1:
return False
elif num in base_primes:
return True
else:
for value in base_primes: # making sure value does not have prime factors in
if num not in base_primes and num % value == 0:
return False
data = initial_data(num)
s = data[1]
d = data[0]
res = False
testing_values = []
if num < 3317044064679887385961981:
testing_values = test_values(num) # Get values of a to be used from test_values
else:
testing_values = [2, min(num - 1, int(2 * (math.log1p(num - 1))**2))]
for a in testing_values:
for r in range(1, s + 1):
power = (2**r)*d
if pow(a, d, num) != 1 and pow(a, power, num) != 1:
res = False
elif pow(a, d, num) == 1 or pow(a, power, num) == 1:
return True
else:
continue
if res:
return False
else:
return False
print(rabin_miller(5547337572376305111955330958342147474062293202868155909393))
对于大于64位的值,这将非常快速地工作,任何旨在提高准确性和效率(时间效率)代码的提示和注释都是受欢迎的。
base_primes列表是使用和改进版本获得的 此问题中的代码:Primality testing: How to make sure not to test numbers which are multiples of already tested numbers?
答案 1 :(得分:0)
以下是随机测试的实现:
import random
#The following function finds s and d in
#n-1 = 2^s*d with d odd
def findSD(n):
s = 0
d = n-1
while d % 2 == 0:
s = s + 1
d = d//2
return s,d
def checkBase(a,n):
s,d = findSD(n)
x = pow(a,d,n)
if x == 1 or x == n-1:
return "probable prime"
else:
for i in range(s-1):
x = pow(x,2,n)
if x == 1:
return "composite"
elif x == n-1:
return "probable prime"
#if you get to this stage, -1 not reached despite s-1
#squarings -- so must be composite
return "composite"
def MSR(n,k):
#tests is an odd number is prime
for i in range(k):
a = random.randint(2,n-2)
if checkBase(a,n) == "composite":
return "composite"
#if you get here n has survived k potential witnesses, so
return "probable prime"
def prime(n):
smallPrimes = [2,3,5,7,11,13,17,19]
for p in smallPrimes:
if n == p:
return True
elif n % p == 0:
return False
if MSR(n,20) == "composite":
return False
else:
return True
def prime(n):
smallPrimes = [2,3,5,7,11,13,17,19]
for p in smallPrimes:
if n == p:
return True
elif n % p == 0:
return False
if MSR(n,20) == "composite":
return False
else:
return True
你可以用它捕捉素数:
def findPrime(maxN):
while True:
n = random.randint(3,maxN)
if prime(n):
return n
典型运行:
>>> findPrime(2**512)
3416363469318261052788311737860856549293100664891633139661459849835325883152102949928216754211470387640525391249585700324869443369023574938398397274187333