I'm a little bit confused, how to do this. I know I can use Random class to generate random numbers, but I don't know how to specify and generate 8-byte number?
Thanks, Vuk
I agree with @aioobe' point about Random using a 48-bit seed. SecureRandom is a better solution. However to answer the OP's questions of how to use the Random class and still allow for all possible 8-byte values is to reset the seed periodically.
int counter = 0;
Random rand = new Random();
Random rand2 = new Random();
if (++counter == 0) rand = new Random(); // reset every 4 billion values.
long randomLong = rand.nextLong() ^ rand2.nextLong() << 1;
Random only allows a sequence of 2^47 long values. By using two Random generators, one which keeps jumping around in the sequence, you get two 2^47 * 2^47 possible values. The use of << 1 is to avoid the impact of having both randoms having the same seed (in which case ^ would produce 0 for 4 billion values in a row)
You should note that the java.util.Random
class uses a 48-bit seed, so not all 8-byte values (sequences of 64 bits) can be generated using this class. Due to this restriction I suggest you use SecureRandom
and the nextBytes
method in this situation.
The usage is quite similar to the java.util.Random
solution.
SecureRandom sr = new SecureRandom();
byte[] rndBytes = new byte[8];
sr.nextBytes(rndBytes);
Here is the reason why a 48-bit seed is not enough:
Random
class implements a pseudo random generator which means that it is deterministic.Random
determines the future sequence of bits.Random
object.Based on @Peter Lawreys excellent answer (it deserves more upvotes!): Here is a solution for creating a java.util.Random
with 2×48-bit seed. That is, a java.util.Random
instance capable of generating all possible long
s.
class Random96 extends Random {
int count = 0;
ExposedRandom extra48bits;
class ExposedRandom extends Random {
public int next(int bits) { // Expose the next-method.
return super.next(bits);
}
}
@Override
protected int next(int bits) {
if (count++ == 0)
extra48bits = new ExposedRandom();
return super.next(bits) ^ extra48bits.next(bits) << 1;
}
}
It can be done either with byte array of length 8:
byte[] byteArray = new byte[8];
random.nextBytes(byteArray);
or with a variable of type long
(which represents 8-byte numbers):
long randomLong = random.nextLong();
The long
type is an 8 byte signed integer, so Random.nextLong()
seems to do what you want. Or if you need a byte array as result:
byte[] result = new byte[8];
Random.nextBytes(result);
A little adjusting from the code here:
import java.util.Random;
/** Generate 10 random integers in the range 0..99. */
public final class RandomByte {
public static final void main(String... aArgs){
log("Generating 10 random integers in range 0..255.");
//note a single Random object is reused here
Random randomGenerator = new Random();
for (int idx = 1; idx <= 10; ++idx){
int randomInt = randomGenerator.nextInt(256);
// int randomInt = randomGenerator.nextBytes(256);
log("Generated : " + randomInt);
}
log("Done.");
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
Some further reading: Math.random() versus Random.nextInt(int)