Pseudo-random number generation library and tools. Part of the OneJoker project.

Project maintained by Lee Daniel Crocker
Lee's blog is etceterology.

onejoker
CC-0: To the extent possible under law, I, Lee Daniel Crocker waive all copyright and related or neighboring rights to all creative works original to me.

Using the library in your Java code

Quickstart

Java package com.onejoker.randlib provides two ways to interact with the library. You can create Generator objects with a specific algorithm and call its methods, or you can just call the static methods of the same name to get the library’s “default” generator. Here’s a simple example of using the C API to print 10 random numbers in the range 0 to 99, using the Mersenne Twister algorithm:

import com.onejoker.randlib.*;

public class Hello {
    static { System.loadLibrary("ojrand"); }

    private static final int[] gSeed = { 0x123, 0x234, 0x345, 0x456 };

    public static void main(String[] args) {
        Generator g = new Generator("mt19937");
        g.seed(gSeed);

        for (int i = 0; i < 20; ++i) {
            System.out.printf("%12d ", g.next32());
            if (4 == (i % 5)) System.out.printf("\n");
        }
    }
}

Note that you must load the shared library before using the class. In the example above we first create a new generator object. The generator is automatically seeded appropriately from whatever randomness is available from your operating system, but we seed it from an array here (this is often handy for testing; in this case, it allows us to test against the reference implementation of the algorithm). Finally, the next32() method fetches random 32-bit integers.

Basic generator functions

Generator()

Creates a new generator using the algorithm specified by the single argument, either by name or number. With no argument, a reasonable default algorithm will be chosen. See the static methods below for how to get information on the available algorithms. The generator objects returned by this function are totally independent of each other, regardless of algorithm. In particular, if you create two generators with the same algorithm and same seed, they will independently produce the same stream of random numbers (this can be handy for writing test programs, for example).

seed()

With no argument, seeds the given generator with random values derived from whatever entropy is available from your operating system. The size of the seed will be chosen to suit the algorithm. You can also pass an integer value or an array of integers. If you need to save the value of a system-generated seed for reproduction later, you will have to instead call the static getSystemEntropy() (see below) and seed with the result.

reseed()

Applies a new seed to an existing generator to change its state “on the fly” without re-initializing. This function should not be needed by most applications. It could be used, for example, to occasionally add extra system entropy to a generator to make it more cryptographically secure. This eliminates reproducibility.

discard(int count)

Advances the generator count steps wihout producing actual output. This is roughly equivalent to calling next32() (see below) count times, though it is faster due to reduced function call overhead. Some generator algorithms benefit from discarding some number of values after initialization before using their output.

Producing output

Now that you’ve created and generator and seeded it, you can use it to produce random numbers in various ways. All of these functions can also be called statically to use the built-in “default” generator.

int next32()

Produces a random 32-bit unsigned integer. All of the algorithms included in ojrandlib are natively 32-bit generators, so the most basic way to get random values is to get them as 32-bit unsigned integers. All of the other producer functions are based on this one.

int next16()

Produce a 16-bit random unsigned integer.

long next64()

Produce a 64-bit random unsigned integer.

int rand(int limit)

Produces a random integer in the range 0 to (limit-1). This is the most useful function for randomly choosing from among a small set of alternatives, for example, selecting a random card from a deck of cards. The numbers are guaranteed to be balanced. That is, if called with a limit of 3, you will get the values 0, 1, and 2 with exactly equal probability. The maximum limit for this function is 32768.

double nextDouble()

Produces a random double value uniformly distributed in the half-open interval [0.0, 1.0). That is, it may produce the value 0.0, but will never produce 1.0, and will produce every representable value in between with equal probability.

double nextSignedDouble()

Produces a random double value uniformly distributed in the open interval (-1.0, 1.0). That is, it will never produce the values -1.0 or 1.0, and will produce every representable value in between with equal probability.

double nextExponential()

Produces a random double value with a probability density of e-x.

double nextNormal()

Produces a random double value normally distributed about a mean of 0.0 with a standard deviation of 1.0.

Non-generator functions

These static methods do not require a generator object because they provide information or services independent of any particular generator.

int[] getSystemEntropy(int count)

Returns an array of random ints from whatever source of randomness your OS provides. On Linux-like systems, these will be from /dev/urandom. On Windows, CryptGenRandom() from the cryptography library will be used. If neither of these is available, the system time and process ID will be used. You should only need to use this function manually if you need both a good quality seed for a generator and need to save it for reproducibility later. Otherwise, simply using seed() on the generator is much simpler.

int[] getRandomOrg(int count)

Returns an array of random ints from the website random.org, which provides random numbers based on atmospheric noise. It is recommended that this be used for seeding PRNGs or other applications that don’t need large quantities of random numbers. The service is limited in speed by your Internet connection and limited in quantity to a daily quota, because it is a free service (although you can pay them for a larger quota).

int algorithmCount()

Returns the number of algorithms available in the system.

String algorithmName(int a)

Returns the name of the algorithm at the given index (beginning at 1). An argument of 0 returns the name of the “default” generator.