펄 28/13 ≈ 2.15
sub r{$s^=~($s^=$s/7215)<<8}
여기에 로그 파일
펄 29/13 ≈ 2.23
sub r{$s^=~($s^=$s<<8)/60757}
여기에 로그 파일
이것들은 오른쪽 시프트 대신 부동 소수점 나누기를 사용하여 Xorshift 의 변형입니다 . 두 테스트 모두 15 개 중 13 개 테스트를 통과하고 테스트 6과 7 만 실패합니다.
사이클의 길이는 확실하지 않지만 다음 코드가 단기간에 종료되지 않기 때문에 전체 2 32 일 가능성이 큽니다 .
$start = r();
$i++ while $start != r();
print $i;
펄 39/10 = 3.9
$s=$^T;sub r{~($s=$s*$s%4294969373)||r}
참고 : Blum-Blum-Shub-esque PRNG를 찾고 있다면 Keith Randall의 솔루션 이 이들 중 하나보다 훨씬 낫습니다.
아래의 원래 솔루션과 마찬가지로 Blum Blum Shub도 한 가지 큰 차이점으로 구현되었습니다. 나는 2 32 보다 약간 큰 계수 ( M = 50971 • 84263 )를 사용하며, 값이 유효한 32 비트 정수 (즉, 2 32 보다 크지 않음)가 될 때마다 다음 값을 대신 회전. 본질적으로 이러한 값은 잘라 내고 나머지 회전은 그대로두고 분포는 거의 균일합니다.
도움이 된 것 같습니다. 이전과 동일한 9 가지 테스트를 통과 할뿐만 아니라 이제 최소 거리 테스트를 통과했습니다. 샘플 로그 파일은 여기 에서 찾을 수 있습니다 .
펄 33/9 ≈ 3.67 (잘못된?)
$s=$^T;sub r{$s=$s*$s%4294951589}
참고 : 범위의 최상위 0.00037 %는 절대로 관찰되지 않으므로이 솔루션은 유효하지 않은 것으로 간주 될 수 있습니다.
Blum Blum Shub 의 빠르고 더러운 구현 . 나는 다음과 같은 결과를 주장한다.
1. passed - Birthday Spacings
2. FAILED - Overlapping Permutations
3. passed - Ranks of 31x31 and 32x32 Matrices
4. passed - Ranks of 6x8 Matrices
5. FAILED - Monkey Tests on 20-bit Words
6. FAILED - Monkey Tests OPSO, OQSO, DNA
7. FAILED - Count the 1s in a Stream of Bytes
8. passed - Count the 1s for Specific Bytes
9. passed - Parking Lot Test
10. FAILED - Minimum Distance Test
11. passed - Random Spheres Test
12. FAILED - The Squeeze Test
13. passed - Overlapping Sums Test
14. passed - Runs Test
15. passed - The Craps Test
샘플 로그 파일은 여기 에서 찾을 수 있습니다 . 결과에 대해 이의를 제기하십시오. diehard 용 파일은 다음과 같은 방식으로 생성 될 수 있습니다.
print pack('N', r()) for 1..4194304
그런 다음 출력을 파일로 파이핑합니다. 최소 거리는 지나간 것으로 보이지만 여러 번 실행하면 항상 1.0에 매우 가깝습니다 . 이는 실패를 나타냅니다.
세부
일반적으로 Blum Blum Shub는 끔찍한 PRNG이지만 좋은 모듈러스를 선택하면 성능을 향상시킬 수 있습니다. M 내가 선택한이다 611207 • 7027 . 이들 주요 요인 p 및 q 는 모두 모듈 형 잔류 물 3 (mod 4) 및 gcd (φ (p-1), φ (q-1)) = 2 를 가지며, 가능한 한 낮습니다.
이것들이 위키 페이지에 나열된 유일한 기준이지만 충분하지는 않습니다. 내가 시도한 거의 모든 모듈로가 모든 테스트에 실패했습니다. 그러나 몇 가지 테스트를 통과하는 소수가 있으며, 내가 선택한 테스트는 어떤 이유로 든 예외적으로 좋은 것으로 보입니다.
마지막으로, 테스트 5 자체는 PRNG가 얼마나 좋은지에 대한 상당히 좋은 지표 인 것 같습니다. 테스트 5를 거의 통과 하지 못하면 나머지는 훌륭하게 실패합니다.
보너스 : Perl 62/14 ≈ 4.43
$t=$^T;sub r{$t|=(($s=$s/2|$t%2<<31)^($t/=2))<<31for 1..37;$t}
괴짜를 위해서만, 이것은 NES의 원래 Tetris에서 사용 된 32 비트 버전의 PRNG입니다. 놀랍게도 15 개의 테스트 중 14 개를 통과했습니다!
1. passed - Birthday Spacings
2. passed - Overlapping Permutations
3. passed - Ranks of 31x31 and 32x32 Matrices
4. passed - Ranks for 6x8 Matrices
5. passed - Monkey Tests on 20-bit Words
6. passed - Monkey Tests OPSO, OQSO, DNA
7. FAILED - Count the 1s in a Stream of Bytes
8. passed - Count the 1s for Specific Bytes
9. passed - Parking Lot Test
10. passed - Minimum Distance Test
11. passed - Random Spheres Test
12. passed - The Squeeze Test
13. passed - Overlapping Sums Test
14. passed - Runs Test
15. passed - The Craps Test
여기 전에 샘플 로그 파일을 사용할 수 있습니다 .
분명히, 1..37
비트는 정확한 전사가 아닙니다. 원래 버전에서 엔트로피 루틴은 초당 60 회 업데이트 된 다음 사용자 간격에 따라 크게 임의의 간격으로 쿼리됩니다. ROM을 분해해야하는 사람은 엔트로피 루틴을 시작하십시오 0xAB47
.
파이썬 스타일의 의사 코드 :
carry = entropy_1 & 1
entropy_1 >>= 1
entropy_2 = (entropy_2 >> 1) | (carry << 31)
carry = (entropy_1 & 1) ^ (entropy_2 & 1)
entropy_1 |= carry << 31