bb.util
Class RandomUtil

java.lang.Object
  extended by bb.util.RandomUtil

public final class RandomUtil
extends Object

Provides static utility methods relating to Random.

This class is multithread safe: all of its fields are multithread safe types.

Author:
Brent Boyer
See Also:
Wikipedia article on random numbers, Random Generators, Tests for Random Number Generators, The chi-squared test, Java code using thread behavior to generate random numbers

Nested Class Summary
static class RandomUtil.UnitTest
          See the Overview page of the project's javadocs for a general description of this unit test class.
 
Field Summary
private static AtomicLong id
           
private static ThreadLocal<ec.util.MersenneTwisterFast> threadLocal
           
 
Constructor Summary
private RandomUtil()
          This private constructor suppresses the default (public) constructor, ensuring non-instantiability.
 
Method Summary
static ec.util.MersenneTwisterFast get()
          Returns a MersenneTwisterFast instance that is local to the calling thread, so thread contention is guaranteed to never occur.
static long makeSeed()
          This method first attempts to generate a high quality seed by calling makeSeedSecure.
static long makeSeedSecure()
          Returns makeSeedSecure("SHA1PRNG").
static long makeSeedSecure(SecureRandom random)
          Returns NumberUtil.bytesBigEndianToLong( random.generateSeed(8) ).
static long makeSeedSecure(String algorithm)
          Returns makeSeedSecure( SecureRandom.getInstance(algorithm) ).
static long makeSeedSecure(String algorithm, String provider)
          Returns makeSeedSecure( SecureRandom.getInstance(algorithm, provider) ).
static long makeSeedUnique()
          This seed value generating function attempts to satisfy these goals: return a unique result for each call of this method return a unique series of results for each different JVM invocation return results which are uniformly spread around the range of all possible long values It uses the following techniques: an internal serial id field is incremented upon each call, so each call is guaranteed a different value; this field determines the high order bits of the result each call uses the result of System.nanoTime to determine the low order bits of the result; this should be different each time the JVM is run (assuming that the system time is different) a hash algorithm is applied to the above numbers before putting them into the high and low order parts of the result Warnings: the uniqueness goals cannot be guaranteed because the hash algorithm, while it is of high quality, is not guaranteed to be a 1-1 function (i.e. 2 different input ints might get mapped to the same output int).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

id

private static final AtomicLong id

threadLocal

private static final ThreadLocal<ec.util.MersenneTwisterFast> threadLocal
Constructor Detail

RandomUtil

private RandomUtil()
This private constructor suppresses the default (public) constructor, ensuring non-instantiability.

Method Detail

makeSeed

public static long makeSeed()
This method first attempts to generate a high quality seed by calling makeSeedSecure. This result should be of extremely high, cryptographic quality (i.e. possibly come in part from a low level hardware source like diode noise, or at least from something like /dev/random, as well as perhaps also satisfy some uniqueness aspects). If any Exception is thrown by this step, it is caught and a value of 0 is assigned to the seed.

This method then generates an additional seed by calling makeSeedUnique which is highly likely to satisfy some uniqueness requirements. This second seed defends against potential problems in certain implementations of SecureRandom (or lack thereof) on some platforms.

A bitwise XOR of the two seeds is finally returned.

See Also:
My forum posting

makeSeedSecure

public static long makeSeedSecure()
                           throws NoSuchAlgorithmException
Returns makeSeedSecure("SHA1PRNG").

Throws:
NoSuchAlgorithmException - if the SHA1PRNG algorithm is not available in the caller's environment

makeSeedSecure

public static long makeSeedSecure(String algorithm)
                           throws NoSuchAlgorithmException
Returns makeSeedSecure( SecureRandom.getInstance(algorithm) ).

Throws:
NoSuchAlgorithmException - if the requested algorithm is not available in the caller's environment

makeSeedSecure

public static long makeSeedSecure(String algorithm,
                                  String provider)
                           throws NoSuchAlgorithmException,
                                  NoSuchProviderException,
                                  IllegalArgumentException
Returns makeSeedSecure( SecureRandom.getInstance(algorithm, provider) ).

Throws:
NoSuchAlgorithmException - if the requested algorithm is not available from the provider
NoSuchProviderException - if the provider has not been configured
IllegalArgumentException - if the provider name is null or empty

makeSeedSecure

public static long makeSeedSecure(SecureRandom random)
                           throws IllegalArgumentException
Returns NumberUtil.bytesBigEndianToLong( random.generateSeed(8) ).

Throws:
IllegalArgumentException - if random == null

makeSeedUnique

public static long makeSeedUnique()
This seed value generating function attempts to satisfy these goals:
  1. return a unique result for each call of this method
  2. return a unique series of results for each different JVM invocation
  3. return results which are uniformly spread around the range of all possible long values
It uses the following techniques:
  1. an internal serial id field is incremented upon each call, so each call is guaranteed a different value; this field determines the high order bits of the result
  2. each call uses the result of System.nanoTime to determine the low order bits of the result; this should be different each time the JVM is run (assuming that the system time is different)
  3. a hash algorithm is applied to the above numbers before putting them into the high and low order parts of the result

Warnings:

  1. the uniqueness goals cannot be guaranteed because the hash algorithm, while it is of high quality, is not guaranteed to be a 1-1 function (i.e. 2 different input ints might get mapped to the same output int).
  2. the result returned by this method is not cryptographically strong because there is insufficient entropy in the sources used (serial number and system time)


get

public static ec.util.MersenneTwisterFast get()
Returns a MersenneTwisterFast instance that is local to the calling thread, so thread contention is guaranteed to never occur.