;;;; -*- Mode: Lisp; Base: 10; Syntax: ANSI-Common-Lisp; Package: cl-user; Coding: utf-8 -*- ;;;; Copyright © 2025 David Mullen. License: Zero-Clause BSD. Origin: (in-package :cl-user) (defun get-weyl-seed () (with-open-file (stream "/dev/urandom" :element-type '(unsigned-byte 64)) ;; From : "The increment S must be odd to ensure ;; the maximum period of the Weyl sequence. All the other variables can be initialized ;; by using any number. We suggest seeding S by an odd number and setting all other ;; elements to zero for the sake of simplicity, in single-stream applications." (logior (the (unsigned-byte 64) (read-byte stream)) 1))) (defun make-cwg64 (&optional (x 0) (a 0) (weyl 0) (s (get-weyl-seed))) "Construct and initialize 64-bit Collatz-Weyl Generator function." (macrolet ((collatz^weyl () ;; "The main types of transformations performed by the original Collatz ;; function are bitwise shifts of the state by 1 bit or the additions ;; of a number to it followed by a bitwise shift. All three proposed ;; Collatz-Weyl Generators above also contain this transformation, ;; which induces arithmetical chaos when combined with multiplication. ;; Using bitwise OR with the number 1 on one of the factors gives ;; slightly better statistical results, according to our experiments." `(logxor (ldb (byte 64 0) (* (ash x -1) (logior a 1))) weyl)) (step-collatz-weyl-generator () `(setq a (ldb (byte 64 0) (+ a x)) weyl (ldb (byte 64 0) (+ weyl s)) x (ldb (byte 64 0) (collatz^weyl))))) ;; "In multi-stream applications, to ensure the complete independence of the 264 streams, ;; the first 48 and 96 states of each stream should be skipped in the CWG64 and CWG128-64, ;; and the CWG128 generators, respectively. Otherwise, minor correlations may occur in the ;; first outputs of the successively initialized streams, especially if they are initialized ;; by using the numbers 1, 3, 5, ... or another counter." (loop repeat 48 do (step-collatz-weyl-generator) finally (return (lambda () (step-collatz-weyl-generator) ;; "In each generator, the lower bits of X are XORed ;; with the upper bits of A in the output scrambler, ;; due to the fact that the lower bits of X do not ;; have sufficient statistical quality." (logxor (ash a -48) x))))))