1 6 21 22 package de.schlichtherle.crypto.generators; 23 24 import java.security.SecureRandom ; 25 import java.util.Random ; 26 27 import org.bouncycastle.crypto.Digest; 28 import org.bouncycastle.crypto.digests.SHA256Digest; 29 30 38 public class DigestRandom extends Random { 39 40 private static final SecureRandom seeder = new SecureRandom (); 41 42 private final byte[] in; 43 private long counter; 44 45 private final Digest digest; 46 47 private final byte[] out; 48 private int outOff; 49 50 public DigestRandom(Digest digest) { 51 this.digest = digest; 52 final int size = digest.getDigestSize(); 53 in = new byte[size]; 54 out = new byte[size]; 55 outOff = size; 56 57 seeder.nextBytes(in); 66 67 long time = System.currentTimeMillis(); 69 for (int i = Math.min(size, 8); --i >= 0; ) { 70 in[i] ^= time; time >>= 8; 72 } 73 } 74 75 82 synchronized public void nextBytes(byte[] bytes) { 83 for (int i = bytes.length; --i >= 0; ) { 84 update(); 85 bytes[i] = out[outOff++]; 86 } 87 } 88 89 103 final protected int next(final int numBits) { 104 final int numBytes = (numBits + 7) >>> 3; 106 int next = 0; 107 for (int i = numBytes; --i >= 0; ) { 108 update(); 109 next = (next << 8) | (out[outOff++] & 0xFF); 110 } 111 112 return next >>> ((numBytes << 3) - numBits); } 114 115 private void update() { 116 if (outOff >= out.length) { 117 long counter = ++this.counter; 118 for (int i = in.length; --i >= 0; ) { 119 counter += in[i] & 0xff; 120 in[i] = (byte) counter; 121 counter >>>= 8; 122 } 123 digest.update(in, 0, in.length); 124 digest.doFinal(out, 0); 125 outOff = 0; 126 } 127 } 128 } 129 | Popular Tags |