Skip to content

Commit 725834b

Browse files
Anzoteh96cclauss
andcommitted
Added binary exponentiaion with respect to modulo (TheAlgorithms#1428)
* Added binary exponentiaion with respect to modulo * Added miller rabin: the probabilistic primality test for large numbers * Removed unused import * Added test for miller_rabin * Add test to binary_exp_mod * Removed test parameter to make Travis CI happy * unittest.main() # doctest: +ELLIPSIS ... * Update binary_exp_mod.py * Update binary_exp_mod.py * Update miller_rabin.py * from .prime_check import prime_check Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent aa18600 commit 725834b

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

maths/binary_exp_mod.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
def bin_exp_mod(a, n, b):
2+
"""
3+
>>> bin_exp_mod(3, 4, 5)
4+
1
5+
>>> bin_exp_mod(7, 13, 10)
6+
7
7+
"""
8+
# mod b
9+
assert not (b == 0), "This cannot accept modulo that is == 0"
10+
if n == 0:
11+
return 1
12+
13+
if n % 2 == 1:
14+
return (bin_exp_mod(a, n - 1, b) * a) % b
15+
16+
r = bin_exp_mod(a, n / 2, b)
17+
return (r * r) % b
18+
19+
20+
if __name__ == "__main__":
21+
try:
22+
BASE = int(input("Enter Base : ").strip())
23+
POWER = int(input("Enter Power : ").strip())
24+
MODULO = int(input("Enter Modulo : ").strip())
25+
except ValueError:
26+
print("Invalid literal for integer")
27+
28+
print(bin_exp_mod(BASE, POWER, MODULO))

maths/miller_rabin.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import random
2+
3+
from .binary_exp_mod import bin_exp_mod
4+
5+
6+
# This is a probabilistic check to test primality, useful for big numbers!
7+
# if it's a prime, it will return true
8+
# if it's not a prime, the chance of it returning true is at most 1/4**prec
9+
def is_prime(n, prec=1000):
10+
"""
11+
>>> from .prime_check import prime_check
12+
>>> all(is_prime(i) == prime_check(i) for i in range(1000))
13+
True
14+
"""
15+
if n < 2:
16+
return False
17+
18+
if n % 2 == 0:
19+
return n == 2
20+
21+
# this means n is odd
22+
d = n - 1
23+
exp = 0
24+
while d % 2 == 0:
25+
d /= 2
26+
exp += 1
27+
28+
# n - 1=d*(2**exp)
29+
count = 0
30+
while count < prec:
31+
a = random.randint(2, n - 1)
32+
b = bin_exp_mod(a, d, n)
33+
if b != 1:
34+
flag = True
35+
for i in range(exp):
36+
if b == n - 1:
37+
flag = False
38+
break
39+
b = b * b
40+
b %= n
41+
if flag:
42+
return False
43+
count += 1
44+
return True
45+
46+
47+
if __name__ == "__main__":
48+
n = abs(int(input("Enter bound : ").strip()))
49+
print("Here's the list of primes:")
50+
print(", ".join(str(i) for i in range(n + 1) if is_prime(i)))

0 commit comments

Comments
 (0)