Scheme 米勒-拉宾试验(SICP 1.28)
费马测试的一个变体是米勒-拉宾测试(Miller 1976;拉宾1980),它不能被愚弄。这是从Fermat小定理的另一种形式开始的,该定理指出,如果n是素数且a是小于n的任何正整数,则提升到(n-1)次方的a与模n的1全等 为了通过Miller-Rabin测试测试数字n的素性,我们选择一个小于n的随机数a,并使用Scheme 米勒-拉宾试验(SICP 1.28),scheme,primes,sicp,modular-arithmetic,primality-test,Scheme,Primes,Sicp,Modular Arithmetic,Primality Test,费马测试的一个变体是米勒-拉宾测试(Miller 1976;拉宾1980),它不能被愚弄。这是从Fermat小定理的另一种形式开始的,该定理指出,如果n是素数且a是小于n的任何正整数,则提升到(n-1)次方的a与模n的1全等 为了通过Miller-Rabin测试测试数字n的素性,我们选择一个小于n的随机数a,并使用expmod过程将a提升到(n-1)阶幂模n。然而,每当我们在expmod中执行平方步骤时,我们都会检查是否发现了一个“1模n的非平凡平方根”,即一个不等于1或n-1的数,其平方等于1
expmod
过程将a提升到(n-1)阶幂模n。然而,每当我们在expmod
中执行平方步骤时,我们都会检查是否发现了一个“1模n的非平凡平方根”,即一个不等于1或n-1的数,其平方等于1模n
可以证明,如果1的非平凡平方根存在,那么n不是素数。还可以证明,如果n是不是素数的奇数,那么,对于至少一半的数aexpmod
程序,以在发现非平凡平方根为1时发出信号,并使用类似于fermat测试的程序来执行Miller-Rabin测试。通过测试各种已知素数和非素数来检查您的程序。提示:使expmod
信号返回0是一种方便的方法
这就是我目前所拥有的
(define (square x) (* x x))
(define (even? n) (= (remainder n 2)))
(define (expmod-signal b n m)
(define (check a)
(and (not (= a 1))
(not (= a (- n 1)))
(= (square a) (remainder 1 n))))
(cond ((= n 0) 1)
((check b) 0)
((even? n) (remainder (square (expmod-signal b (/ n 2) m)) m))
(else (remainder (* b (expmod-signal b (- n 1) m)) m))))
(define (miller-rabin n)
(define (fail? n a)
(or (= n 0) (not (= n a))))
(define (try a)
(cond ((= a 1) #t)
((fail? (expmod-signal a (- n 1) n) a) #f)
(else (try (- a 1)))))
(try (- n 1)))
我想我正确地实现了miller-rabin
,但我不明白修改后的expmod
应该如何工作。你是在方格前还是方格后查号码?通过阅读问题我不知道。我通过使用expmod信号
内部的expmod
的原始定义解决了这个问题。在我的测试中,expmod信号
自然地返回零并干扰测试。我误解了check函数,“其平方等于1模n”意味着检查a^2%m=1
。此检查函数的工作方式是,如果参数是1 mod n的非平凡平方根,则返回0,否则返回参数。如果返回零,则零将通过expmod信号的剩余部分传播并返回
(define (square x) (* x x))
(define (even? n) (= (remainder n 2)))
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp) (remainder (square (expmod base (/ exp 2) m)) m))
(else (remainder (* base (expmod base (- exp 1) m)) m))))
(define (expmod-signal b n m)
(define (check a)
(if (and (not (= a 1))
(not (= a (- n 1)))
(= (remainder (square a) n) 1))
0
a))
(cond ((= n 0) 1)
((even? n) (remainder (square (check (expmod b (/ n 2) m))) m))
(else (remainder (* b (expmod b (- n 1) m)) m))))
(define (miller-rabin n)
(define (fail? a)
(or (= a 0) (not (= a 1))))
(define (try a)
(cond ((= a 1) #t)
((fail? (expmod-signal a (- n 1) n)) #f)
(else (try (- a 1)))))
(try (- n 1)))