Last active
August 29, 2015 13:56
-
-
Save film42/9036065 to your computer and use it in GitHub Desktop.
Fermat based primality tester written in Clojure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; | |
;; Checkout this page for large prime numbers: http://primes.utm.edu/lists/small/small3.html | |
;; | |
;; Testing a 300 digit prime number | |
(def some-large-prime 290245329165570025116016487217740287508837913295571609463914348778319654489118435855243301969001872061575755804802874062021927719647357060447135321577028929269578574760547268310055056867386875959045119093967972205124270441648450825188877095173754196346551952542599226295413057787340278528252358809329N) | |
(is-prime? some-large-prime) ;;=> true || Elapsed time: 216.512 msecs | |
;; Testing a long even number | |
(def some-long-even-number 709127341927349283740927349823749237492734092873492842N) | |
(is-prime? some-long-even-number) ;;=> false || Elapsed time: 0.478 msecs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn exp [base pow] | |
(reduce * (repeat (bigint pow) (bigint base)))) | |
(defn modexp | |
"Modular Exponentiation. No tail optomized loop/recur, but you'll | |
probably never need it." | |
[base pow n] | |
(if (= pow 0) 1 | |
(let [z (modexp base (bigint (/ pow 2)) n)] | |
(if (even? pow) | |
(mod (exp z 2) n) | |
(mod (* (exp z 2) base) n))))) | |
(defn rand-bigint | |
"Returns a random integer with bitlength n. | |
Credit: http://pastebin.com/KBd862Wr" | |
[n] (bigint (new java.math.BigInteger n (new java.util.Random)))) | |
(defn uniform-number | |
"Return a random number that is between 1 and n-1" | |
[n] (+ 1 (rand-bigint (-> (- n 2) str count)))) | |
(defn is-prime? | |
"Fermat based primality tester" | |
([n] (is-prime? n 20)) | |
([n complexity] | |
(let [pow (dec n)] | |
(loop [k complexity] | |
(if (= k 0) | |
true | |
(let [res (modexp | |
(uniform-number n) pow n)] | |
(if-not (= res 1) | |
false | |
(recur (dec k))))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment