import java.security.MessageDigest; // import java.security.NoSuchAlgorithmException; // public final class SHA1Generator extends RandomNumberGenerator { public final class SHA1Generator { // internal constants private final static int POS_MASK = 0x7fffffff; private final static int LOWBYTE = 0xFF; // internal rng state private byte[] state = new byte[20]; private MessageDigest shamd; // 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 >> 0)); try { shamd = MessageDigest.getInstance("SHA-1"); shamd.update(seedstate); state = shamd.digest(); } catch (java.security.NoSuchAlgorithmException bogus) { System.out.println("java.security.NoSuchAlgorithmException"); System.exit(0); } }; // 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 >> 0)); try { shamd = MessageDigest.getInstance("SHA-1"); shamd.update(parent.state); shamd.update(seedstate); state = shamd.digest(); } catch (java.security.NoSuchAlgorithmException bogus) { System.out.println("java.security.NoSuchAlgorithmException"); System.exit(0); } }; // Return next random number public int nextrand() { int d; shamd.update(state); state = shamd.digest(); d = 0x7f & state[16]; d = (d<<8) | (state[17] & 0xff); d = (d<<8) | (state[18] & 0xff); d = (d<<8) | (state[19] & 0xff); return d; }; // return current random number (no advance) public int rand() { int d; d = 0x7f & state[16]; d = (d<<8) | (state[17] & 0xff); d = (d<<8) | (state[18] & 0xff); d = (d<<8) | (state[19] & 0xff); return d&POS_MASK; }; // 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 r=0; int NUM_RNG_SPAWNS = 1600; SHA1Generator parent = new SHA1Generator(0); SHA1Generator[] child = new SHA1Generator[NUM_RNG_SPAWNS]; 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); } parent = new SHA1Generator(0); for (j=1; j