Paste number 92750: /dev/urandom-state

Index of paste annotations: 1

Paste number 92750: /dev/urandom-state
Pasted by: Krystof
When:7 months, 20 hours ago
Share:Tweet this! | http://paste.lisp.org/+1ZKE
Channel:#lisp
Paste contents:
Raw Source | XML | Display As
;;;; /dev/urandom-state
;;;; Christophe Rhodes <csr21@cantab.net>
;;;; 2009-12-28

;;;; This short file is primarily intended as an example of a
;;;; random-state implementation using SBCL’s embryonic
;;;; CL:RANDOM-STATE protocol.

;;; First, we define a class.  We inherit from both CL:STANDARD-OBJECT
;;; and CL:RANDOM-STATE; we can do this even though CL:RANDOM-STATE is
;;; a CL:STRUCTURE-CLASS (and inherits from CL:STRUCTURE-OBJECT)
;;; because CL:RANDOM-STATE has been declared in its definition as
;;; subclassable.  (For details on this, consult the documentation or,
;;; more realistically, the source code).  We define for this class a
;;; single, :CLASS-allocated slot for an open stream to the
;;; non-blocking random device; strictly speaking this is a
;;; file-descriptor leak, in that it’s only closed when the Lisp
;;; process exits, but there is only one such fd in play per Lisp
;;; image.

(defclass /dev/urandom-state (standard-object random-state)
  ((s :allocation :class
      :initform (open "/dev/urandom" :element-type 'unsigned-byte))))

;;; There are three protocol functions to implement.  The first,
;;; RANDOM-WORD, must return a 32-bit integer from the random state
;;; and update the state.  Since we are reading directly from the
;;; kernel’s entropy pool or PRNG, we don’t have any state to update,
;;; but we must construct our 32-bit word from the octets that we
;;; read.  Calls to CL:RANDOM end up calling this function, whether to
;;; generate an integer or a floating point sample; this protocol
;;; function is also available to be used in layered protocols, for
;;; example for generating samples from particular statistical
;;; distributions.

(defmethod random-word ((state /dev/urandom-state))
  (let ((s (slot-value state 's)))
    (dpb (read-byte s) (byte 8 24)
         (dpb (read-byte s) (byte 8 16)
              (dpb (read-byte s) (byte 8 8) (read-byte s))))))

;;; The other two protocol functions support calls to
;;; CL:MAKE-RANDOM-STATE.  MAKE-RANDOM-STATE-LIKE is called when CL:T
;;; is passed to CL:MAKE-RANDOM-STATE, and must construct a
;;; freshly-initialized random state of the same class.  In this case
;;; that task is easy; we simply construct a new instance of this
;;; class, as we don’t need to do any initialization.

(defmethod make-random-state-like ((state /dev/urandom-state))
  (make-instance '/dev/urandom-state))

;;; COPY-RANDOM-STATE is called when CL:NIL or a CL:RANDOM-STATE
;;; object is passed to CL:MAKE-RANDOM-STATE, and should produce a
;;; copy of the CL:RANDOM-STATE argument it is given in the fifth
;;; sense of the CLHS glossary entry for “copy”: a state that will
;;; produce the same sequence of numbers if CL:RANDOM is called with
;;; the same arguments in the same order.  In this case, we can’t do
;;; that, so we signal an continuable error instead, allowing the user
;;; to generate a fresh random state instead.

(defmethod copy-random-state ((state /dev/urandom-state))
  (cerror "Create a fresh random state instead" "Cannot copy[5] ~S" state)
  (make-random-state-like state))

Annotations for this paste:

Annotation number 1: literate programming
Pasted by: Krystof
When:7 months, 20 hours ago
Share:Tweet this! | http://paste.lisp.org/+1ZKE/1
Paste contents:
Raw Source | Display As
\documentclass{article}

\usepackage{fontspec}

\catcode`;=\active
\gdef;{\normalsize\rmfamily\catcode`\ =\active\relax\def\cpar{\ }\def\cspace{ }}
\catcode`\ =\active
\def\cspace{\catcode`;11\relax~}
\gdef {\cspace}
\gdef\cpar{\par}
\def\cnl{\catcode`;=\active\small\ttfamily\cpar\def\cpar{\par}\def\cspace{\catcode`;11\relax~}\relax}
\catcode`\^^M=\active\def^^M{\cnl}
\begin{document}
\input{random.lisp}
\end{document}

Colorize as:
Show Line Numbers
Index of paste annotations: 1

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.