Skip to content

Instantly share code, notes, and snippets.

@zynick
Last active December 16, 2015 17:09
Show Gist options
  • Save zynick/5468171 to your computer and use it in GitHub Desktop.
Save zynick/5468171 to your computer and use it in GitHub Desktop.
Prove that java.util.Random isn't that random after all...
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
/**
* in response to http://jazzy.id.au/default/2010/09/20/cracking_random_number_generators_part_1.html
* <p>
* the code on that website works 1 out of 4 times because, as mentioned by the
* author itself, it isn't complete since he prefer to keep the code easier to
* read and understand.
* <p>
* what i did is just add a 32 bit mask on 2nd random integer when it was cast
* to long to ensure the bits remain the same regardless of positive or negative
* number generated.
* <p>
* runnable code: http://ideone.com/pS58fs
*
* @author zynick
*/
public class GuessRandom {
// copied from Random source code
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
public static void main(String[] args) {
// give me 2 random integer
Random rand = new Random();
int i1 = rand.nextInt();
int i2 = rand.nextInt();
long l1 = i1;
long mask32 = (1L << 32) - 1; // 32 bit masking
long l2 = i2 & mask32;
// find seed
long shiftl1 = l1 << 16;
long find = 0;
for (long i = 0; i < 65536; i++) {
find = shiftl1 + i;
if ((((find * multiplier + addend) & mask) >>> 16) == l2) {
System.out.println("seed found: " + find);
break;
}
}
// test seed
AtomicLong found = new AtomicLong(find);
int predict = next(32, found);
predict = next(32, found);
int expect = rand.nextInt();
System.out.println("Predict: " + predict + "\nExpect : " + expect); // same!
}
// copied from Random source code
protected static int next(int bits, AtomicLong seed) {
long oldseed, nextseed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int) (nextseed >>> (48 - bits));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment