【发布时间】:2019-10-04 08:02:56
【问题描述】:
费马检验的一种变体被称为米勒-拉宾检验(Miller-Rabin 检验)(Miller 1976;Rabin 1980)。这从费马小定理的另一种形式开始,它指出如果 n 是一个素数并且 a 是任何小于 n 的正整数,则 a 的 (n - 1) 次幂等于 1 模 n。
为了通过 Miller-Rabin 测试来测试一个数 n 的素数,我们选择一个小于 n 的随机数 a 并提高a 到 (n - 1)st 幂模 n 使用
expmod过程。但是,每当我们在expmod中执行平方步骤时,我们都会检查是否发现了“1 模 n 的非平凡平方根”,即数不等于 1 或 n - 1,其平方等于 1 模 n。可以证明,如果1的这样一个非平凡平方根存在,那么n不是素数。也可以证明,如果 n 是一个非素数的奇数,那么,对于至少一半的数 a ,计算 an-1 以这种方式将显示 1 模 n 的非平凡平方根。 (这就是为什么 Miller-Rabin 测试不能被愚弄的原因。)
修改
expmod过程以在发现1 的非平凡平方根时发出信号,并使用该过程以类似于fermat-test的过程实现米勒-拉宾测试。通过测试各种已知的素数和非素数来检查你的程序。提示:制作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 应该如何工作。你检查正方形之前的数字还是正方形之后的数字?我不知道从阅读问题。
【问题讨论】:
标签: scheme primes sicp modular-arithmetic primality-test