From c62d5c857045c63208a77f6292d61ab915b63205 Mon Sep 17 00:00:00 2001 From: Flavio De Stefano Date: Sat, 10 Jun 2017 19:09:15 +0200 Subject: [PATCH] Added Miller-Rabin primality test --- algorithm/category.json | 3 +- .../miller_rabin_primality_test/basic/code.js | 91 +++++++++++++++++++ .../miller_rabin_primality_test/basic/data.js | 18 ++++ .../miller_rabin_primality_test/desc.json | 13 +++ 4 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 algorithm/number_theory/miller_rabin_primality_test/basic/code.js create mode 100644 algorithm/number_theory/miller_rabin_primality_test/basic/data.js create mode 100644 algorithm/number_theory/miller_rabin_primality_test/desc.json diff --git a/algorithm/category.json b/algorithm/category.json index bc7eeef4..8795c53b 100644 --- a/algorithm/category.json +++ b/algorithm/category.json @@ -62,7 +62,8 @@ "number_theory": { "list": { "euclidean_algorithm": "Euclidean Algorithm", - "sieve_of_eratosthenes": "Sieve of Eratosthenes" + "sieve_of_eratosthenes": "Sieve of Eratosthenes", + "miller_rabin_primality_test": "Miller-Rabin primality test" }, "name": "Number Theory" }, diff --git a/algorithm/number_theory/miller_rabin_primality_test/basic/code.js b/algorithm/number_theory/miller_rabin_primality_test/basic/code.js new file mode 100644 index 00000000..5e20dd11 --- /dev/null +++ b/algorithm/number_theory/miller_rabin_primality_test/basic/code.js @@ -0,0 +1,91 @@ +// Utility function to do modular exponentiation. +// It returns (x^y) % p +function power(x, y, p) +{ + var res = 1; + x = x % p; + while (y > 0) { + // If y is odd, multiply x with result + if (y & 1) res = (res*x) % p; + // y must be even now + y = y>>1; // y = y/2 + x = (x*x) % p; + } + return res; +} + + +/** + * Determine if N is prime using Miller-Rabin probabilistic algorithm + * @param {Number} n The number + * @param {Number} k An integer that determine the accuracy of the solution + * @return {Boolean} + */ +function testProbablyPrime(n, k) { + logger._print("==> Testing number " + n); + + if (n === 1 || n === 3) { + logger._print("==> Simple case, N is 1 or 3"); + return true; + } + if (n % 2 === 0) { + logger._print("==> Simple case, " + n + " mod 2 = 0"); + return false; + } + + // Write (n - 1) as 2^s * d + var d = n-1; + while (d % 2 === 0) { + d /= 2; + } + logger._print("d = " + d); + + // Do 5 iterations if none supplied + k = k || 5; + var P = 100 * (1 - (1/Math.pow(4, k))); + + WitnessLoop: do { + logger._print("Remaining iterations: #" + k); + + var a = 2 + Math.floor(Math.random() * (n - 4)); + logger._print("--> first test with random = " + a); + + // Compute a^d % n + var x = power(a, d, n); + + if (x === 1 || x === n - 1) { + logger._print("--> continue WitnessLoop, x = 1 or x = n-1"); + continue; + } + + logger._print("--> second test"); + + // Keep squaring x while one of the following doesn't + // happen + // (i) d does not reach n-1 + // (ii) (x^2) % n is not 1 + // (iii) (x^2) % n is not n-1 + var i = d; + while (i != n-1) { + x = (x * x) % n; + i *= 2; + + if (x == 1) { + logger._print("--> exiting, " + n + " is composite"); + return false; + } + + if (x == n-1) { + logger._print("--> continue WitnessLoop"); + continue WitnessLoop; + } + } + + logger._print("--> exiting, " + n + " is composite 'cause (n-1) is reached"); + return false; + + } while (--k); + + logger._print("End of tests, " + n + " is probably prime with probabilty of " + P + "%"); + return true; +} \ No newline at end of file diff --git a/algorithm/number_theory/miller_rabin_primality_test/basic/data.js b/algorithm/number_theory/miller_rabin_primality_test/basic/data.js new file mode 100644 index 00000000..fed79228 --- /dev/null +++ b/algorithm/number_theory/miller_rabin_primality_test/basic/data.js @@ -0,0 +1,18 @@ +var logger = new LogTracer(); + +var a = Math.floor(Math.random()*300); if (a % 2 === 0) a += 1; +testProbablyPrime(a); +logger._print("----------"); + +var a = Math.floor(Math.random()*300); if (a % 2 === 0) a += 1; +testProbablyPrime(a); +logger._print("----------"); + +var a = Math.floor(Math.random()*300); if (a % 2 === 0) a += 1; +testProbablyPrime(a); +logger._print("----------"); + +testProbablyPrime(151); +logger._print("----------"); + +testProbablyPrime(199, 10); \ No newline at end of file diff --git a/algorithm/number_theory/miller_rabin_primality_test/desc.json b/algorithm/number_theory/miller_rabin_primality_test/desc.json new file mode 100644 index 00000000..a4ee242e --- /dev/null +++ b/algorithm/number_theory/miller_rabin_primality_test/desc.json @@ -0,0 +1,13 @@ +{ + "Miller-Rabin primality test": "Determines whether a given number is prime", + "Complexity": { + "time": "$O(klog^{3}(n)))$", + "probability": "$1 - (1/(4^{k}))$" + }, + "References": [ + "Wikipedia" + ], + "files": { + "basic": "Miller Rabin primality test" + } +} 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