01: package org.bouncycastle.crypto.prng;
02:
03: /**
04: * A thread based seed generator - one source of randomness.
05: * <p>
06: * Based on an idea from Marcus Lippert.
07: * </p>
08: */
09: public class ThreadedSeedGenerator {
10: private class SeedGenerator implements Runnable {
11: private volatile int counter = 0;
12: private volatile boolean stop = false;
13:
14: public void run() {
15: while (!this .stop) {
16: this .counter++;
17: }
18:
19: }
20:
21: public byte[] generateSeed(int numbytes, boolean fast) {
22: Thread t = new Thread(this );
23: byte[] result = new byte[numbytes];
24: this .counter = 0;
25: this .stop = false;
26: int last = 0;
27: int end;
28:
29: t.start();
30: if (fast) {
31: end = numbytes;
32: } else {
33: end = numbytes * 8;
34: }
35: for (int i = 0; i < end; i++) {
36: while (this .counter == last) {
37: try {
38: Thread.sleep(1);
39: } catch (InterruptedException e) {
40: // ignore
41: }
42: }
43: last = this .counter;
44: if (fast) {
45: result[i] = (byte) (last & 0xff);
46: } else {
47: int bytepos = i / 8;
48: result[bytepos] = (byte) ((result[bytepos] << 1) | (last & 1));
49: }
50:
51: }
52: stop = true;
53: return result;
54: }
55: }
56:
57: /**
58: * Generate seed bytes. Set fast to false for best quality.
59: * <p>
60: * If fast is set to true, the code should be round about 8 times faster when
61: * generating a long sequence of random bytes. 20 bytes of random values using
62: * the fast mode take less than half a second on a Nokia e70. If fast is set to false,
63: * it takes round about 2500 ms.
64: * </p>
65: * @param numBytes the number of bytes to generate
66: * @param fast true if fast mode should be used
67: */
68: public byte[] generateSeed(int numBytes, boolean fast) {
69: SeedGenerator gen = new SeedGenerator();
70:
71: return gen.generateSeed(numBytes, fast);
72: }
73: }
|