Skip to content

Commit c62d5c8

Browse files
committed
Added Miller-Rabin primality test
1 parent 6b5f1a8 commit c62d5c8

File tree

4 files changed

+124
-1
lines changed

4 files changed

+124
-1
lines changed

algorithm/category.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
"number_theory": {
6363
"list": {
6464
"euclidean_algorithm": "Euclidean Algorithm",
65-
"sieve_of_eratosthenes": "Sieve of Eratosthenes"
65+
"sieve_of_eratosthenes": "Sieve of Eratosthenes",
66+
"miller_rabin_primality_test": "Miller-Rabin primality test"
6667
},
6768
"name": "Number Theory"
6869
},
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Utility function to do modular exponentiation.
2+
// It returns (x^y) % p
3+
function power(x, y, p)
4+
{
5+
var res = 1;
6+
x = x % p;
7+
while (y > 0) {
8+
// If y is odd, multiply x with result
9+
if (y & 1) res = (res*x) % p;
10+
// y must be even now
11+
y = y>>1; // y = y/2
12+
x = (x*x) % p;
13+
}
14+
return res;
15+
}
16+
17+
18+
/**
19+
* Determine if N is prime using Miller-Rabin probabilistic algorithm
20+
* @param {Number} n The number
21+
* @param {Number} k An integer that determine the accuracy of the solution
22+
* @return {Boolean}
23+
*/
24+
function testProbablyPrime(n, k) {
25+
logger._print("==> Testing number " + n);
26+
27+
if (n === 1 || n === 3) {
28+
logger._print("==> Simple case, N is 1 or 3");
29+
return true;
30+
}
31+
if (n % 2 === 0) {
32+
logger._print("==> Simple case, " + n + " mod 2 = 0");
33+
return false;
34+
}
35+
36+
// Write (n - 1) as 2^s * d
37+
var d = n-1;
38+
while (d % 2 === 0) {
39+
d /= 2;
40+
}
41+
logger._print("d = " + d);
42+
43+
// Do 5 iterations if none supplied
44+
k = k || 5;
45+
var P = 100 * (1 - (1/Math.pow(4, k)));
46+
47+
WitnessLoop: do {
48+
logger._print("Remaining iterations: #" + k);
49+
50+
var a = 2 + Math.floor(Math.random() * (n - 4));
51+
logger._print("--> first test with random = " + a);
52+
53+
// Compute a^d % n
54+
var x = power(a, d, n);
55+
56+
if (x === 1 || x === n - 1) {
57+
logger._print("--> continue WitnessLoop, x = 1 or x = n-1");
58+
continue;
59+
}
60+
61+
logger._print("--> second test");
62+
63+
// Keep squaring x while one of the following doesn't
64+
// happen
65+
// (i) d does not reach n-1
66+
// (ii) (x^2) % n is not 1
67+
// (iii) (x^2) % n is not n-1
68+
var i = d;
69+
while (i != n-1) {
70+
x = (x * x) % n;
71+
i *= 2;
72+
73+
if (x == 1) {
74+
logger._print("--> exiting, " + n + " is composite");
75+
return false;
76+
}
77+
78+
if (x == n-1) {
79+
logger._print("--> continue WitnessLoop");
80+
continue WitnessLoop;
81+
}
82+
}
83+
84+
logger._print("--> exiting, " + n + " is composite 'cause (n-1) is reached");
85+
return false;
86+
87+
} while (--k);
88+
89+
logger._print("End of tests, " + n + " is probably prime with probabilty of " + P + "%");
90+
return true;
91+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var logger = new LogTracer();
2+
3+
var a = Math.floor(Math.random()*300); if (a % 2 === 0) a += 1;
4+
testProbablyPrime(a);
5+
logger._print("----------");
6+
7+
var a = Math.floor(Math.random()*300); if (a % 2 === 0) a += 1;
8+
testProbablyPrime(a);
9+
logger._print("----------");
10+
11+
var a = Math.floor(Math.random()*300); if (a % 2 === 0) a += 1;
12+
testProbablyPrime(a);
13+
logger._print("----------");
14+
15+
testProbablyPrime(151);
16+
logger._print("----------");
17+
18+
testProbablyPrime(199, 10);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"Miller-Rabin primality test": "Determines whether a given number is prime",
3+
"Complexity": {
4+
"time": "$O(klog^{3}(n)))$",
5+
"probability": "$1 - (1/(4^{k}))$"
6+
},
7+
"References": [
8+
"<a href='https://www.wikiwand.com/en/Miller%E2%80%93Rabin_primality_test'>Wikipedia</a>"
9+
],
10+
"files": {
11+
"basic": "Miller Rabin primality test"
12+
}
13+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy