# Some (More) C++ PRNG Implementations

Nearly a year ago, I wrote a post suggesting some good alternatives to PCG. As part of that post, I included links to C++ implementations of those PRNGs, following C++-11 conventions (although omitting rarely-used features such as state I/O).

Since that post, I've written my own C++ implementations of a few more generation schemes. Links and brief descriptions below.

### JSF: Bob Jenkins's Small/Fast Chaotic PRNG

The gist `jsf.hpp`

contains an implementation of Bob Jenkins's “Small/Fast PRNG”, which is based on a random invertible mapping—what some call a “*chaotic PRNG*”. I discussed this generator in a previous post, but the short version is that it passes stringent statistical tests, seems to be quite annoying to predict, and works well. It's also very fast.

My C++ implementation provides the standard `jsf64`

and `jsf32`

variants, as well as a number of variations Jenkins suggests that use different constants that should also work well. It also includes some tiny versions, `jsf16`

and `jsf8`

, which are mostly designed for experimental use (these smaller variants should not be expected to pass extensive statistical tests).

### GJrand: David Blackman's Chaotic PRNG

The gist `gjrand.hpp`

contains an implementation of David Blackman's `gjrand`

PRNG, which is based on a random invertible mapping that includes a counter to guarantee no small cycles. I will discuss this generator in a future post, but the short version is that it passes stringent statistical tests, and works well. It's also fast, although not quite as fast as JSF, but on the other hand appears to have slightly stronger bit-mixing properties than JSF.

My C++ implementation provides the standard `gjrand64`

variant, and at my request Blackman also made a `gjrand32`

variant. It also includes some tiny versions, `gjrand16`

and `gjrand8`

, which are mostly designed for experimental use (these smaller variants should not be expected to pass extensive statistical tests).

### SFC: Chris Doty-Humphrey's Chaotic PRNG

The gist `sfc.hpp`

contains an implementation of Chris Doty-Humphrey's `sfc`

PRNG, which is based on a random invertible mapping that includes a counter to guarantee no small cycles. I will discuss this generator in a future post, but the short version is that it passes stringent statistical tests, and works well. It's also very fast, although it appears to have slightly weaker bit-mixing properties than JSF or `gjrand`

.

My C++ implementation provides the standard `sfc64`

and `sfc32`

variants. It also includes some tiny versions, `sfc16`

and `sfc8`

, which are mostly designed for experimental use (these smaller variants should not be expected to pass extensive statistical tests).

### Lehmer: A 128-Bit Lehmer PRNG

The gist `lehmer.hpp`

provides a C++ implementation of fast, 128-bit, Lehmer-style PRNGs (MCGs) as discussed in a previous post. On 64-bit x86 CPUs these are some of the fastest good-quality PRNGs I am aware of.

This code requires C++17 and a `__uint128_t`

type (supported by Clang, GCC, and Intel's compiler). It provides `mcg128`

and `mcg128_fast`

, the latter using a 64-bit multiplicative constant rather than the usual 128-bit constant for additional speed.

### SplitMix: 32-Bit and 64-Bit Output from 128-Bit State

The gist `splitmix.hpp`

provides a C++ implementation of SplitMix, as described by Guy L. Steele, Jr., Doug Lea and Christine H. Flood in the paper *Fast Splittable Pseudorandom Number Generators* and implemented in Java 8 as SplittableRandom (cannonical source code).

This C++ implementation avoids the bugs present in implementations directly derived from the (erroneous) code in the SplitMix paper. Without these bugs it has all properties, good and bad, that are inherent in SplitMix's design (discussed at length in previous posts). In particular, the 64-bit–output variant, `splitmix64`

, may not be suitable for general-purpose use because it has the property that each number is only output once (similar to `_once_insecure`

PCG variants), which can be detected as a deviation from random behavior by statistical tests. The 32-bit–output variant, `splitmix32`

, does not have this issue.

Unlike the other implementations described in this post, this implementation includes both jump-ahead and distance operations (most implementations of SplitMix do not offer these features, although they are quite easy to provide). Also, in contrast to other implementations, the two variants are represented as separate classes (although it is possible to cast between them; `splitmix32`

is a subclass of `splitmix64`

).

### Arc4: A Classic

The gist `arc4.hpp`

provides a C++ implementation of Arc4, based on the OpenBSD implementation (specifically the version found in Apple's Libc-594.9.4).

As a general-purpose PRNG, it is rather slow, and it is also slow by the standards of modern cryptographic PRNGs and is also considered too weak to use for cryptographic purposes. It is, however, of historical interest and can be useful in testing to see how sensitive a algorithms are to PRNG speed.

### And more…

Other generators are linked to in my earlier post. I have also updated my C++ implementation of Xoroshiro to reflect the most recent changes made by Vigna & Blackman, and created a C++ implementation of their newest scheme, Xoshiro.