package org.spongycastle.crypto.prng; /** * A thread based seed generator - one source of randomness. * <p> * Based on an idea from Marcus Lippert. * </p> */ public class ThreadedSeedGenerator { private class SeedGenerator implements Runnable { private volatile int counter = 0; private volatile boolean stop = false; public void run() { while (!this.stop) { this.counter++; } } public byte[] generateSeed( int numbytes, boolean fast) { Thread t = new Thread(this); byte[] result = new byte[numbytes]; this.counter = 0; this.stop = false; int last = 0; int end; t.start(); if(fast) { end = numbytes; } else { end = numbytes * 8; } for (int i = 0; i < end; i++) { while (this.counter == last) { try { Thread.sleep(1); } catch (InterruptedException e) { // ignore } } last = this.counter; if (fast) { result[i] = (byte) (last & 0xff); } else { int bytepos = i/8; result[bytepos] = (byte) ((result[bytepos] << 1) | (last & 1)); } } stop = true; return result; } } /** * Generate seed bytes. Set fast to false for best quality. * <p> * If fast is set to true, the code should be round about 8 times faster when * generating a long sequence of random bytes. 20 bytes of random values using * the fast mode take less than half a second on a Nokia e70. If fast is set to false, * it takes round about 2500 ms. * </p> * @param numBytes the number of bytes to generate * @param fast true if fast mode should be used */ public byte[] generateSeed( int numBytes, boolean fast) { SeedGenerator gen = new SeedGenerator(); return gen.generateSeed(numBytes, fast); } }