그래서 저는 작은 RSA 알고리즘을 구현했으며 그 과정에서 큰 소수를 찾는 함수를 작성했습니다.
먼저 소수성을 테스트하는 prime?
함수를 작성한 다음 두 가지 버전의 프라임 검색 함수를 작성했습니다. 첫 번째 버전에서는 소수를 칠 때까지 임의의 BigIntegers를 테스트합니다. 두 번째 버전에서는 임의의 BigInteger를 샘플링 한 다음 소수점을 찾을 때까지 증가시킵니다. 이 코드를 실행왜 primes를 샘플링하는 두 가지 방법이 똑같이 오래 실행됩니까?
(defn resampling []
(let [rnd (Random.)]
(->> (repeatedly #(BigInteger. 512 rnd))
(take-while (comp not prime?))
(count))))
(defn incrementing []
(->> (BigInteger. 512 (Random.))
(iterate inc)
(take-while (comp not prime?))
(count)))
(let [n 100]
{:resampling (/ (reduce + (repeatedly n resampling)) n)
:incrementing (/ (reduce + (repeatedly n incrementing)) n)})
는 증분 함수 리샘플링 기능에 대한 310.74 332.41 두 평균을 수득 하였다.
이제 첫 번째 숫자가 나에게 완벽합니다. prime number theorem은 n
의 소수가 약 n*ln(n)
(여기서, ln
은 자연 로그)이라는 것을 나타냅니다. 따라서 인접한 소수 간의 거리는 약 n*ln(n) - (n-1)*ln(n-1) ≈ (n - (n - 1))*ln(n) = ln(n)
입니다 (큰 값이 n
ln(n) ≈ ln(n - 1)
인 경우). 512 비트 정수를 샘플링하기 때문에 소수 사이의 거리가 ln(2^512) = 354.89
부근에있을 것으로 기대합니다. 따라서 무작위 추출은 프라임을 치기 전에 평균적으로 약 354.89 번의 시도가 필요하다.
저를위한 수수께끼는 왜 증가 기능이 다만 많은 단계를 취하는 지입니다. 소수가 355 단위 떨어져있는 그리드에서 다트를 던지는 것을 상상해 보면, 평균적으로 두 개의 소수 사이의 중심을 치고 있기 때문에 다음 상위 높은 소수로 걸어가는 데 평균적으로 많은 단계가 소요됩니다.
은 (prime?
의 코드는 조금 긴 것입니다. 당신은 here 좀 걸릴 수 있습니다.)
아마도 증분 방법으로 테스트하는 숫자의 절반이 짝수이기 때문일 수 있습니까? – rossum
@ resum은'resampling' 메쏘드와 같기 때문에 그것이 이유라고 생각하지 않습니다. –
그것을 확인해 봅니다. 비슷한 번호가 있습니다. 나의 수학은 꽤 녹슬었고 처음부터 그렇게 좋은 것은 아니지만 소수의 분포를 이해할 수있는 것은 https://en.wikipedia.org/wiki/Poisson_distribution이다.이 숫자는 여기에서 의미가있다 : http : //phillipmfeldman.org/mathematics/primes.html "두 개의 독립적 인 푸 아송 확률 변수의 합은 또 다른 푸 아송 확률 변수를 산출합니다." 이 질문은 cs 또는 수학 사이트 중 하나에 훨씬 적합 할 것입니다. – Oleg