package aalg.crypto;

import java.math.BigInteger;

public abstract class RandomGeneratorImpl implements IRandomGenerator {
	
	// Method nextNumber generates larger number that is required and than reduces it
	// modulo required size. EXTRA_BYTES says how larger it should be - bigger means
	// slower calculation but more flat probability distribution.
	private static final int EXTRA_BYTES = 8;
	
	/**
	 * Returns random BigInterer from range <minNumber; maxNumber).
	 * @param minNumber minimal generated number (inclusive)
	 * @param maxNumber maximal generated number (exclusive)
	 * @return random BigInterer
	 */
	@Override
	public BigInteger nextNumber(final BigInteger minNumber, final BigInteger maxNumber) {
		final BigInteger diff = maxNumber.subtract (minNumber);
		final int neededBytes = (diff.bitLength() + Byte.SIZE - 1) / Byte.SIZE + EXTRA_BYTES;
		
		final byte[] bytes = new byte[neededBytes];
		
		for (int i = 0; i < neededBytes; i++)
			bytes[i] = nextByte();
		
		final BigInteger randomNumber = new BigInteger(1, bytes).mod(diff);
		
		return minNumber.add (randomNumber);
	}
}
