mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-27 23:11:09 +00:00
1400cb86ff
* Fixes (#5434) * Update ciphers.rabin_miller.py maths.miller_rabin.py * Fixing ERROR maths/miller_rabin.py - ModuleNotFoundError and changing project_euler's isPrime to is_prime function names * Update sol1.py * fix: try to change to list * fix pre-commit * fix capital letters * Update miller_rabin.py * Update rabin_miller.py Co-authored-by: John Law <johnlaw.po@gmail.com>
224 lines
3.2 KiB
Python
224 lines
3.2 KiB
Python
# Primality Testing with the Rabin-Miller Algorithm
|
|
|
|
import random
|
|
|
|
|
|
def rabinMiller(num: int) -> bool:
|
|
s = num - 1
|
|
t = 0
|
|
|
|
while s % 2 == 0:
|
|
s = s // 2
|
|
t += 1
|
|
|
|
for trials in range(5):
|
|
a = random.randrange(2, num - 1)
|
|
v = pow(a, s, num)
|
|
if v != 1:
|
|
i = 0
|
|
while v != (num - 1):
|
|
if i == t - 1:
|
|
return False
|
|
else:
|
|
i = i + 1
|
|
v = (v**2) % num
|
|
return True
|
|
|
|
|
|
def is_prime_low_num(num: int) -> bool:
|
|
if num < 2:
|
|
return False
|
|
|
|
lowPrimes = [
|
|
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,
|
|
383,
|
|
389,
|
|
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 in lowPrimes:
|
|
return True
|
|
|
|
for prime in lowPrimes:
|
|
if (num % prime) == 0:
|
|
return False
|
|
|
|
return rabinMiller(num)
|
|
|
|
|
|
def generateLargePrime(keysize: int = 1024) -> int:
|
|
while True:
|
|
num = random.randrange(2 ** (keysize - 1), 2 ** (keysize))
|
|
if is_prime_low_num(num):
|
|
return num
|
|
|
|
|
|
if __name__ == "__main__":
|
|
num = generateLargePrime()
|
|
print(("Prime number:", num))
|
|
print(("is_prime_low_num:", is_prime_low_num(num)))
|