Fix typos in docstrings and function names.
[sbcl.git] / src / code / target-random.lisp
index b4cb278..f886832 100644 (file)
 (defun make-random-state (&optional state)
   #!+sb-doc
   "Make a random state object. The optional STATE argument specifies a seed
-  for deterministic pseudo-random number generation.
+for deterministic pseudo-random number generation.
 
-  As per the Common Lisp standard,
-  - If STATE is NIL or not supplied or is NIL, return a copy of the default
+As per the Common Lisp standard,
+- If STATE is NIL or not supplied, return a copy of the default
   *RANDOM-STATE*.
-  - If STATE is a random state, return a copy of it.
-  - If STATE is T, return a randomly initialized state (using operating-system
-  provided randomness source where available, otherwise a poor substitute
-  based on internal time and pid)
+- If STATE is a random state, return a copy of it.
+- If STATE is T, return a randomly initialized state (using operating-system
+  provided randomness where available, otherwise a poor substitute based on
+  internal time and PID).
 
-  See SB-EXT:SEED-RANDOM-STATE for a SBCL extension to this functionality."
+See SB-EXT:SEED-RANDOM-STATE for a SBCL extension to this functionality."
   (/show0 "entering MAKE-RANDOM-STATE")
   (check-type state (or boolean random-state))
   (seed-random-state state))
 
+(defun fallback-random-seed ()
+  ;; When /dev/urandom is not available, we make do with time and pid
+  ;; Thread ID and/or address of a CONS cell would be even better, but...
+  (/show0 "No /dev/urandom, using randomness from time and pid")
+  (+ (get-internal-real-time)
+     (ash (sb!unix:unix-getpid) 32)))
+
+#!-win32
+(defun os-random-seed ()
+  (or
+   ;; On unices, we try to read from /dev/urandom and pass the results
+   ;; to our (simple-array (unsigned-byte 32) (*)) processor below.
+   ;; More than 256 bits would provide a false sense of security.
+   ;; If you need more bits than that, you probably also need
+   ;; a better algorithm too.
+   (ignore-errors
+    (with-open-file (r "/dev/urandom" :element-type '(unsigned-byte 32)
+                                      :direction :input :if-does-not-exist :error)
+      (let ((a (make-array '(8) :element-type '(unsigned-byte 32))))
+        (assert (= 8 (read-sequence a r)))
+        a)))
+   (fallback-random-seed)))
+
+#!+win32
+(defun os-random-seed ()
+  (/show0 "Getting randomness from CryptGenRandom")
+  (or (sb!win32:crypt-gen-random 32)
+      (fallback-random-seed)))
+
 (defun seed-random-state (&optional state)
   #!+sb-doc
   "Make a random state object. The optional STATE argument specifies a seed
-  for deterministic pseudo-random number generation.
+for deterministic pseudo-random number generation.
 
-  As per the Common Lisp standard for MAKE-RANDOM-STATE,
-  - If STATE is NIL or not supplied or is NIL, return a copy of the default
+As per the Common Lisp standard for MAKE-RANDOM-STATE,
+- If STATE is NIL or not supplied, return a copy of the default
   *RANDOM-STATE*.
-  - If STATE is a random state, return a copy of it.
-  - If STATE is T, return a randomly initialized state (using operating-system
-  provided randomness source where available, otherwise a poor substitute
-  based on internal time and pid)
+- If STATE is a random state, return a copy of it.
+- If STATE is T, return a randomly initialized state (using operating-system
+  provided randomness where available, otherwise a poor substitute based on
+  internal time and pid).
 
-  As a supported SBCL extension, we also support receiving as a seed an object
-  of the following types:
-  - (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))
-  - UNSIGNED-BYTE
-  While we support arguments of any size and will mix the provided bits into
-  the random state, it is probably overkill to provide more than 256 bits worth
-  of actual information.
+As a supported SBCL extension, we also support receiving as a seed an object
+of the following types:
+- (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))
+- UNSIGNED-BYTE
+While we support arguments of any size and will mix the provided bits into
+the random state, it is probably overkill to provide more than 256 bits worth
+of actual information.
 
-  This particular SBCL version also accepts an argument of the following type:
-  - (SIMPLE-ARRAY (UNSIGNED-BYTE 32) (*))
+This particular SBCL version also accepts an argument of the following type:
+(SIMPLE-ARRAY (UNSIGNED-BYTE 32) (*))
 
-  This particular SBCL version uses the popular MT19937 PRNG algorithm, and its
-  internal state only effectively contains about 19937 bits of information.
-  http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+This particular SBCL version uses the popular MT19937 PRNG algorithm, and its
+internal state only effectively contains about 19937 bits of information.
+http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
 "
   (etypecase state
     ;; Easy standard cases
     ;; Standard case, less easy: try to randomly initialize a state.
     ((eql t)
      (/show0 "getting randomness from the operating system")
-     (seed-random-state
-      (or
-       ;; On unices, we try to read from /dev/urandom and pass the results
-       ;; to our (simple-array (unsigned-byte 32) (*)) processor below.
-       ;; More than 256 bits would provide a false sense of security.
-       ;; If you need more bits than that, you probably also need
-       ;; a better algorithm too.
-       #!-win32
-       (ignore-errors
-         (with-open-file (r "/dev/urandom" :element-type '(unsigned-byte 32)
-                            :direction :input :if-does-not-exist :error)
-           (let ((a (make-array '(8) :element-type '(unsigned-byte 32))))
-             (assert (= 8 (read-sequence a r)))
-             a)))
-       ;; When /dev/urandom is not available, we make do with time and pid
-       ;; Thread ID and/or address of a CONS cell would be even better, but...
-       (progn
-         (/show0 "No /dev/urandom, using randomness from time and pid")
-         (+ (get-internal-real-time)
-            #!+unix (ash (sb!unix:unix-getpid) 32))))))
+     (seed-random-state (os-random-seed)))
     ;; For convenience to users, we accept (simple-array (unsigned-byte 8) (*))
     ;; We just convert it to (simple-array (unsigned-byte 32) (*)) in a
     ;; completely straightforward way.