I am creating a deep clone for some object. The object contains a Random.
Is it good practice to retrieve the seed from the Random? If so,
This can be done via reflection, although there is a small quirk:
Random r = ...; //this is the random you want to clone
long theSeed;
try
{
Field field = Random.class.getDeclaredField("seed");
field.setAccessible(true);
AtomicLong scrambledSeed = (AtomicLong) field.get(r); //this needs to be XOR'd with 0x5DEECE66DL
theSeed = scrambledSeed.get();
}
catch (Exception e)
{
//handle exception
}
Random clonedRandom = new Random(theSeed ^ 0x5DEECE66DL);
The magic number 0x5DEECE66DL comes from the source code of Random.java, where seeds are given an "initial scramble" of:
private static final long multiplier = 0x5DEECE66DL;
private static final long mask = (1L << 48) - 1;
//...
private static long initialScramble(long seed) {
return (seed ^ multiplier) & mask;
}
which XOR's them with a random number and truncates them to 48 bits. Thus, to recreate the seed state, we have to XOR the seed we pulled.