计算机程序的构造和解释 练习题1.28

首先我们对“1取模n的非凡平方根”解释一下,如果x^2≡1 mod n 且x ≠(1,n-1),则称 x为“1取模n的非凡平方根"。
为什么1和n-1不是非凡平方根呢,因为他们太平凡了,随便给一个数n,这两个数的平方mod n都的结果都是1。1不用说了,1的平方是1,1 mod n结果还是1,(n-1)^2 = n^2-2n+1,如果对这个二项式除以n,前面两项都有n这个因数,余数肯定是1。

然后我们重新加入Miller-Rabin检查,顺带检查之前的Carmichael数。

#lang racket
(define (square x) (* x x))
(define (runtime) ( current-inexact-milliseconds )) 

(define (nontrivial-square-root-test a n)
  (and (not (= a (- n 1))) (not (= a 1)) (= (remainder (square a) n) 1)))


(define (expmod base exp m)
         (cond ((= exp 0) 1)
         		//如果存在非凡平方根,判断结束,返回0,证明数不是素数
               ((nontrivial-square-root-test base m) 0)
               ((even? exp)
                (remainder(square (expmod base (/ exp 2 )m)) m))
               (else
                (remainder(* base (expmod base (- exp 1) m)) m))))

//把原来的 a的n次方 取模n 等于a变成 a的n-1次方 取模n 等于1
(define (fermat-test n)
  (define (try-it a)
    (= (expmod a (- n 1) n) 1))
  (try-it (+ 1 (random (- n 1)))))

(define (fast-prime? n times)
  (cond ((= times 0) #t)
        ((fermat-test n) (fast-prime? n (- times 1)))
        (else #f)))


(define (timed-rabin-prime-test n) 
	(start-prime-test n (runtime)))
(define (start-prime-test n start-time)
	(if (fast-prime? n 1000)
		(begin (report-prime n (- (runtime) start-time)) #t) #f))
(define(report-prime n elapsed-time)
  	(newline)
        (display n)
	(display " usetime ")
	(display elapsed-time))
	
(define (search-for-primes n count)
  (cond((= count 0) n )
  ((timed-rabin-prime-test n) (search-for-primes (+ n 1) (- count 1)))
    (else (search-for-primes (+ n 1) count))))

(search-for-primes 100000 3)
(search-for-primes 1000000 3)
(search-for-primes 10000000 3)
(search-for-primes 100000000 3)
(search-for-primes 1000000000 3)

(timed-rabin-prime-test 561)
(timed-rabin-prime-test 1105)
(timed-rabin-prime-test 1729)
(timed-rabin-prime-test 2465)
(timed-rabin-prime-test 2821)

运行结果:

100003 usetime 3.99609375
100019 usetime 3.998046875
100043 usetime 4.9970703125100044

1000003 usetime 4.99755859375
1000033 usetime 3.997314453125
1000037 usetime 4.9973144531251000038

10000019 usetime 4.99658203125
10000079 usetime 6.99609375
10000103 usetime 5.99340820312510000104

100000007 usetime 7.984619140625
100000037 usetime 6.986328125
100000039 usetime 7.99462890625100000040

1000000007 usetime 7.995361328125
1000000009 usetime 7.994873046875
1000000021 usetime 9.9934082031251000000022
#f
#f
#f
#f
#f

后面几个Carmichael数都为false,无法通过Miller-Rabin检查。

发布了27 篇原创文章 · 获赞 1 · 访问量 477

猜你喜欢

转载自blog.csdn.net/holybird0213/article/details/104637618