练习1.28。不能被愚弄的Fermat测试的一个变体称为Miller-Rabin测试(Miller 1976; Rabin 1980)。这个 从另一种形式的费马小定理开始,该定理指出 如果n是素数而a是任何小于n的正整数, 然后提升到(n - 1)st幂与1 modulo n一致。至 通过Miller-Rabin测试测试数n的素数,我们选择了一个 随机数a< n并使用a将(n - 1)st次幂提高到n expmod程序。但是,每当我们执行平方步骤时 在expmod中,我们检查一下我们是否发现了一个非平凡的广场 1模的根,''也就是说,一个不等于1或n - 1的数字 square等于1 modulo n。有可能证明,如果这样的话 存在1的非平凡平方根,则n不是素数。也是 可以证明如果n是非素数的奇数,那么, 对于至少一半的数字a< n,以这种方式计算^(n-1)将 揭示1模数n的非平凡平方根。 (这就是为什么 Miller-Rabin测试不能被愚弄。)将expmod过程修改为 如果它发现一个非平凡的平方根1,则发出信号,并使用它 使用类似于的程序实施Miller-Rabin测试 费马测试。通过测试各种已知质数来检查您的程序 非素数。提示:制作expmod信号的一种便捷方法是 它返回0。
(define (fast-prime? n)
(define (fast-prime-iter n counter)
(cond ((= counter 1) #t) ; There is no need to check 1
((miller-rabin-test n counter)
(fast-prime-iter n (- counter 1)))
(else
(newline)
(display counter)
#f)))
(fast-prime-iter n (- n 2)))
(define (miller-rabin-test n a)
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(nontrivial-square-root?
(remainder (square (expmod base (/ exp 2) m))
m)))
(else
(remainder (* base (expmod base (- exp 1) m))
m))))
(= (expmod a (- n 1) n) 1))
(define (nontrivial-square-root? val)
(if (= val 1)
0
val))
我的想法是过滤掉那些所谓的"非平凡的1个模n"使用nontrivial-square-root?
程序。如果0
为1,则会返回(remainder (square (expmod base (/ exp 2) m)) m)
,在这种情况下,(expmod base (/ exp 2) m)
的平方必须等于1模n(这是因为m
总是等于{{1} }),使它成为一个重要的平方根。
虽然n
过滤掉了carmichael数字,例如561,1105,1729,2465,2821和6601,但7和13等素数也被报告为复合数。
造成这些假阴性的原因是什么?
答案 0 :(得分:3)
引号的重要部分标有粗体文字:
但是,每当我们在expmod中执行平方步骤时,我们都会检查是否发现了一个“模数n的非平凡平方根”,即数字不等于1或n - 1 其平方等于1模n
因此,在你平方并取余数之前,你必须检查参数不是1或n - 1.这会发生,例如,如果你打电话给var galleryTop = new Swiper('.gallery-top', {
spaceBetween: 15,
slidesPerView: 2,
centeredSlides: true,
loop: true
});
var galleryThumbs = new Swiper('.gallery-thumbs', {
spaceBetween: 10,
centeredSlides: true,
slidesPerView: 'auto',
touchRatio: 0.2,
slideToClickedSlide: true,
loop: true
});
galleryTop.params.control = galleryThumbs;
galleryThumbs.params.control = galleryTop;
。通过递归递归,您会注意到有一个评估为(miller-rabin-test 5 3)
的调用(nontrivial-square-root? (remainder (square 4) 5))
。但是,5仍然是素数,因为4是5 - 1。
因此,在平方部分,您可以调用以下函数:
(nontrivial-square-root? 1)
其中参数是(define (sqrmod-with-check val n)
(let ((sqrmod (remainder (square val) n)))
(cond ((or (= val (- n 1)) (= val 1)) sqrmod)
((= sqrmod 1) 0)
(else sqrmod))))
调用和expmod
。除了在我们找到1模数n的非平凡平方根的情况下,它为你做正方形和余数,当它返回0时。我把它除了三个条件,而不是两个,只是因为可读性。