import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Random; public class IsaacRandom extends Random { private static final long serialVersionUID = 1L; private final int[] randResult = new int[256]; // output of last generation private int valuesUsed; // the number of values already used up from randResult // internal generator state private final int[] mm = new int[256]; private int aa, bb, cc; public IsaacRandom() { super(0); init(null); } public IsaacRandom(int[] seed) { super(0); setSeed(seed); } public IsaacRandom(String seed) { super(0); setSeed(seed); } private void generateMoreResults() { cc++; bb += cc; for (int i=0; i<256; i++) { int x = mm[i]; switch (i&3) { case 0: aa = aa^(aa<<13); break; case 1: aa = aa^(aa>>>6); break; case 2: aa = aa^(aa<<2); break; case 3: aa = aa^(aa>>>16); break; } aa = mm[i^128] + aa; int y = mm[i] = mm[(x>>>2) & 0xFF] + aa + bb; randResult[i] = bb = mm[(y>>>10) & 0xFF] + x; } valuesUsed = 0; } private static void mix(int[] s) { s[0]^=s[1]<<11; s[3]+=s[0]; s[1]+=s[2]; s[1]^=s[2]>>>2; s[4]+=s[1]; s[2]+=s[3]; s[2]^=s[3]<<8; s[5]+=s[2]; s[3]+=s[4]; s[3]^=s[4]>>>16; s[6]+=s[3]; s[4]+=s[5]; s[4]^=s[5]<<10; s[7]+=s[4]; s[5]+=s[6]; s[5]^=s[6]>>>4; s[0]+=s[5]; s[6]+=s[7]; s[6]^=s[7]<<8; s[1]+=s[6]; s[7]+=s[0]; s[7]^=s[0]>>>9; s[2]+=s[7]; s[0]+=s[1]; } private void init(int[] seed) { if (seed != null && seed.length != 256) { seed = Arrays.copyOf(seed, 256); } aa = bb = cc = 0; int[] initState = new int[8]; Arrays.fill(initState, 0x9e3779b9); // the golden ratio for (int i=0; i<4; i++) { mix(initState); } for (int i=0; i<256; i+=8) { if (seed != null) { for (int j=0; j<8; j++) { initState[j] += seed[i+j]; } } mix(initState); for (int j=0; j<8; j++) { mm[i+j] = initState[j]; } } if (seed != null) { for (int i=0; i<256; i+=8) { for (int j=0; j<8; j++) { initState[j] += mm[i+j]; } mix(initState); for (int j=0; j<8; j++) { mm[i+j] = initState[j]; } } } valuesUsed = 256; // Make sure generateMoreResults() will be called by the next next() call. } @Override protected int next(int bits) { if (valuesUsed == 256) { generateMoreResults(); assert(valuesUsed == 0); } int value = randResult[valuesUsed]; valuesUsed++; return value >>> (32-bits); } @Override public synchronized void setSeed(long seed) { super.setSeed(0); if (mm == null) { // We're being called from the superclass constructor. We don't have our // state arrays instantiated yet, and we're going to do proper initialization // later in our own constructor anyway, so just ignore this call. return; } int[] arraySeed = new int[256]; arraySeed[0] = (int) (seed & 0xFFFFFFFF); arraySeed[1] = (int) (seed >>> 32); init(arraySeed); } public synchronized void setSeed(int[] seed) { super.setSeed(0); init(seed); } public synchronized void setSeed(String seed) { super.setSeed(0); char[] charSeed = seed.toCharArray(); int[] intSeed = new int[charSeed.length]; for (int i=0; i