Primality Checking
May 1, 2009
In a previous exercise you wrote a function that returned a list of prime numbers, and in another exercise you used that function to find a particular prime number. This exercise looks at prime numbers from a different perspective by considering a function that takes a number and determines if it is prime.
The algorithm that we will consider was developed initially by Gary Miller and refined by Michael Rabin, and is probabilistic in nature. It works like this: Express the odd number n to be factored as n = 2^{r} s + 1 with s odd. Then choose a random integer a with 1 ≤ a ≤ n1 and check if a^{s} ≡ 1 (mod n) or a^{2j s} ≡ 1 (mod n) for some 0 ≤ j ≤ r1. (Some browsers render that last equation poorly; it’s a raised to the power 2 to the j times s.) A prime number will pass the check for all a. A composite number will pass the check for about 1/4 of the possible as and fail the check for the remaining 3/4 of the possible as. Thus, to determine if a number n is prime, check multiple as; if k as are checked, this algorithm will err less than one time in 4^{k}. Most primality checkers set k to somewhere between 25 and 50, making the chance of error very small.
Your task is to write a function that determines if an input number n is prime, then to determine if 2^{89}1 is prime. When you are finished, you are welcome to read or run a suggested solution, or post your solution or discuss the exercise in the comments below.
[…] Praxis – Primality Checking By Remco Niemeijer Today’s Programming Praxis problem is about checking whether or not a number is prime. We’re supposed […]
My Haskell solution (see http://bonsaicode.wordpress.com/2009/05/01/programmingpraxisprimalitychecking/ for a version with comments):
import Control.Arrow
import Data.Bits
import Data.List
import System.Random
isPrime :: Integer > StdGen > Bool
isPrime n g =
let (s, d) = (length *** head) . span even $ iterate (flip div 2) (n – 1)
xs = map (expm n d) . take 50 $ randomRs (2, n – 2) g
in all (\x > elem x [1, n – 1] 
any (== n – 1) (take s $ iterate (expm n 2) x)) xs
expm :: Integer > Integer > Integer > Integer
expm m e b = foldl’ (\r (b’, _) > mod (r * b’) m) 1 .
filter (flip testBit 0 . snd) .
zip (iterate (flip mod m . (^ 2)) b) $
takeWhile (> 0) $ iterate (flip shiftR 1) e
main :: IO ()
main = print . isPrime (2 ^ 89 – 1) =<< getStdGen [/sourcecode]
I’m slowly working my way through old exercises now that I have some free time. Here’s
my attempt in Common Lisp; I’m trying to learn the language, even though I already had Pythoned MillerRabin previously.
Wow, so much code needed in OCaml to solve this exercise in a selfcontained fashion! First of all, a generalpurpose function to return a random
Big_int
between 0 and a specifiedmax
(exclusive):(You can’t go much lower level than this.) Next, some utility functions on
Big_int
s:Finally, an imperativestyle RabinMiller test:
Two optimizations were applied: first, the random a should be greater than 1; second, the successive powers of a in the inner loop are calculated inductively by (modular) squaring.
I made a mistake in
random_big_int
. Lines 10 and 11 are wrong, they should read:This is a Haskell program I wrote (ironically enough around May 2009, though I hadn’t heard about this website back then.) This was my first relatively nontrivial Haskell program.
To test 2^89 1 use,
.\millerrabin.exe t 618970019642690137449562111
Rewrote the Haskell MillerRabin in Clojure as my first Clojure program. It is linebyline translation, pretty much. Main difference is that one can’t generate random numbers > 2^63, so that is taken into account when generating tests.
{
{前几天最近这段时间这些天前段时间前些日子没多久前不久前}刚开始{碰啃练习接触学接触到学习} python，现在{碰到遇到遭遇到接触到要用到}验证码问题，{网上上网}{查了下google了一下百度了一下谷歌了一下baidu了一下百度了一会谷歌了一会google了一会搜了一下搜了一会}{相关}{内容知识资料教程}，{知道得知获悉了解到了解好像似乎}用python获取验证码{的人}还是{比较多的不少不在少数挺多的}。自己琢磨了{一番一下一下午一整天一早上一晚上整个上午整个下午整个晚上}，用的是{开源的免费的不用钱的不用银子的不用付费的}打码工具tesseractor，但{始终最后最终后来至今到现在到目前}都没{搞出来搞定成功获取验证码成功获取验证码获取到验证码弄出验证码解决验证码问题搞出验证码}，{不知道不清楚不了解不明白没弄懂没明白没了解没搞清没搞懂没搞明白}是什么{问题原因情况}，难道是{免费没好货免费的问题天下没有免费的午餐}？{有没有有无知不知知不知道有人知道有没人知道有没谁知道有谁知道有谁了解有谁用过}{什么哪个哪些哪一些哪个}付费的{推荐软件平台应用工具}吗？

{前几天最近这段时间这些天前段时间前些日子没多久前不久前}刚开始{碰啃练习接触学接触到学习}
python，现在{碰到遇到遭遇到接触到要用到}验证码问题，{通过测试了下弄了下搞了下}本地可以{解析获取弄搞读取读}出{一个}字符串，{然后但是可是接着不过}再提交{的时候后之后过后以后}这个验证码已经{变改变变化}了，{我}{在这里在这现在如今}想{问咨询询问了解搞明白弄懂}的是{如何怎样怎么}{才}能{保证保持}这两{者个}{一致相同不变}。