// X10 Version Author: J. A. Kuehn, Oak Ridge National Laboratory public final class SHA1Generator extends RandomNumberGenerator { // internal constants private final static int POS_MASK = 0x7fffffff; // private final static int HIGH_BITS = 0x80000000; private final static int LOWBYTE = 0xFF; // private final static int SHA1_BLOCK_SIZE = 64; private final static int SHA1_DIGEST_SIZE = 20; // private final static int SHA1_MASK = SHA1_BLOCK_SIZE - 1; // internal rng state private byte[] state = new byte[SHA1_DIGEST_SIZE]; // 160 bit output representation // private SHA1compiler sha1; // private int[] hash = new int[SHA1_DIGEST_SIZE/4]; // 160 bit internal representation // private int[] wbuf = new int[SHA1_BLOCK_SIZE/4]; // 64 byte internal working buffer // private long count = 0; // 64 bit counter of bytes processed // new rng from seed public SHA1Generator(int seedarg) { byte[] seedstate = new byte[20]; for (int i=0; i<16; i++) seedstate[i]=0; seedstate[16] = (byte)(LOWBYTE & (seedarg >>> 24)); seedstate[17] = (byte)(LOWBYTE & (seedarg >>> 16)); seedstate[18] = (byte)(LOWBYTE & (seedarg >>> 8)); seedstate[19] = (byte)(LOWBYTE & (seedarg)); SHA1compiler sha1 = new SHA1compiler(); sha1.hash(seedstate,20); sha1.digest(state); }; // New rng from existing rng public SHA1Generator(SHA1Generator parent, int spawnnumber) { byte[] seedstate = new byte[4]; seedstate[0] = (byte)(LOWBYTE & (spawnnumber >>> 24)); seedstate[1] = (byte)(LOWBYTE & (spawnnumber >>> 16)); seedstate[2] = (byte)(LOWBYTE & (spawnnumber >>> 8)); seedstate[3] = (byte)(LOWBYTE & (spawnnumber)); SHA1compiler sha1 = new SHA1compiler(); sha1.hash(parent.state,20); sha1.hash(seedstate,4); sha1.digest(state); }; // Return next random number public final int nextrand() { int d; SHA1compiler sha1 = new SHA1compiler(); sha1.hash(state,20); sha1.digest(state); return POS_MASK & (((LOWBYTE & (int)state[16])<<24) | ((LOWBYTE & (int)state[17])<<16) | ((LOWBYTE & (int)state[18])<< 8) | ((LOWBYTE & (int)state[19]))); }; // return current random number (no advance) public final int rand() { int d; return POS_MASK & (((LOWBYTE & (int)state[16])<<24) | ((LOWBYTE & (int)state[17])<<16) | ((LOWBYTE & (int)state[18])<< 8) | ((LOWBYTE & (int)state[19]))); }; // describe the state of the RNG public String showstate() { String[] hex = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; String sha1state = "SHA1 state=|"; for (int i=0; i<20; i++) { sha1state += hex[((state[i]>>4)&0x0F)]; sha1state += hex[((state[i]>>0)&0x0F)]; sha1state += "|"; } return sha1state; }; // describe the RNG public String showtype() { return ("SHA-1 160 bits"); }; public static void main(String[] args) { double et=0.0; int i=0; int j=0; int d=0; int r=0; int NUM_RNG_SPAWNS = 1000000; SHA1Generator parent = new SHA1Generator(0); SHA1Generator child = new SHA1Generator(0); /////////////////////////////// // do 2000, print 10 for (i=0; i<2000; i++) { r=parent.nextrand(); } for (i=0; i<10; i++) { r=parent.nextrand(); System.out.println(parent.showstate()+", NEXT="+r); } /////////////////////////////// // print 20 spawed rngs parent = new SHA1Generator(0); for (j=1; j<20; j++) { child = new SHA1Generator(parent,j); for (i=0; i