initial checkin
authorClaus Gittinger <cg@exept.de>
Thu, 02 Oct 2014 18:24:30 +0200
changeset 3421 ffc828b5799a
parent 3420 f9d2226dbde2
child 3422 2c30d066d988
initial checkin
RandomBlumBlumShub.st
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RandomBlumBlumShub.st	Thu Oct 02 18:24:30 2014 +0200
@@ -0,0 +1,113 @@
+"{ Package: 'stx:libbasic2' }"
+
+Object subclass:#RandomBlumBlumShub
+	instanceVariableNames:'p q m seed'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Magnitude-Numbers'
+!
+
+!RandomBlumBlumShub class methodsFor:'documentation'!
+
+documentation
+"
+    NO WARRANTY
+
+    This generator uses the blum blub shub algorithm to generate random numbers.
+    It is very slow, but considered to provide good random numbers.
+
+    RandomBlumBlumShub new nextInteger
+
+    [see also:]
+        RandomGenerator - the default; uses the machine's /dev/random if available
+        Random  - fast, but generates less quality random numbers
+        RandomTT800 - another random generator
+        RandomParkMiller - another random generator
+        RandomMT19937 - another random generator
+        RandomKISS - another random generator
+        exept:libcrypt - a library containing more stuff based on hashes and cyphers
+
+    [author:]
+        Claus Gittinger.
+"
+! !
+
+!RandomBlumBlumShub class methodsFor:'instance creation'!
+
+new
+    ^ self basicNew 
+        initialize;
+        seed:(Random randomSeed)
+!
+
+new:seed
+    self isSupported ifFalse:[ self error:'this generator needs a cpu with rdgen instruction' ].
+    ^ self basicNew 
+        initialize;
+        seed:seed
+! !
+
+!RandomBlumBlumShub methodsFor:'initialization'!
+
+initialize
+    "The two primes, p and q, should both be congruent to 3 (mod 4)"
+
+    p := 615389388455725613122981570401989286707.
+    q := 8936277569639798554773638405675965349567.
+    m := p * q.
+
+    "/ (p \\ 4) = 3 ifFalse:[ self halt: 'unsuitable p' ].
+    "/ (q \\ 4) = 3 ifFalse:[ self halt: 'unsuitable p' ].
+
+    "
+     self new initialize
+    "
+!
+
+seed:seedArg
+    seed := seedArg.
+
+    self assert:(seed < m).
+    self assert:(seed gcd:m) = 1.
+! !
+
+!RandomBlumBlumShub methodsFor:'random numbers'!
+
+nextBoolean
+    "generates the next random boolean"
+
+    seed := seed*seed \\ m.
+    ^ seed bitTest:1
+!
+
+nextInteger
+    "generates the next integer in 0..FFFFFFFF"
+
+    |num|
+
+    num := 0.
+    32 timesRepeat:[
+        seed := (seed * seed) \\ m.
+        num := (num<<1) + (seed bitAnd:1).
+    ].
+    ^ num.
+
+    "
+     self new nextInteger.
+
+     |r|
+     r := self new
+     100 timesRepeat:[ Transcript showCR:r nextInteger].
+    "
+! !
+
+!RandomBlumBlumShub class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libbasic2/RandomBlumBlumShub.st,v 1.1 2014-10-02 16:24:30 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/libbasic2/RandomBlumBlumShub.st,v 1.1 2014-10-02 16:24:30 cg Exp $'
+! !
+