2

I'm curious if there are seeds for java.util.random which have weird/surprising properties. This has little practical use, but I'm still curious.

edit: by weird/surprising properties I mean repeating values or atypical patterns.

  • 6
    You need to define "weird/surprising properties". – asbachb Aug 04 '22 at 19:31
  • 3
    [Why does this code using random strings print "hello world"?](https://stackoverflow.com/questions/15182496/why-does-this-code-using-random-strings-print-hello-world) – OH GOD SPIDERS Aug 04 '22 at 19:32
  • The correct answer to your question is "no!" Last time I looked, Java used a 48 bit linear congruential generator. That means it has 2^48 possible states internally, a large but finite number, so eventually the states repeat. In other words, the sequence of states (and hence values) generated is a great big cycle. People attribute magic powers to seeds, but all a seed really does is determine the initial state, i.e., the entry point to the cycle. Since all states will eventually be visited, there's nothing weird about any individual state, and thus nothing special about any particular seed. – pjs Aug 06 '22 at 23:18
  • Also note that repeating values or "atypical patterns" would be functions of the generator's algorithm, not of the seed. See https://stackoverflow.com/a/2641020/2166798 for a good perspective on the idea of a "good" seed. As for duplicates, they **should** occur, but only in the right proportions. That was the core of my first published paper back in the 1980's, and contributed to the idea that modern generators should have a state space larger than their output space so they produce duplicate values without duplicating the sequence. Otherwise you can quickly nail them as non-random. – pjs Aug 07 '22 at 01:06

1 Answers1

2

Yes!

The java.util.Random object's constructor takes in a long as an argument. A bit of sifting through internal classes, we find that this long is processed through the following function:

private static long initialScramble(long seed) {
    return (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
}

The goal of this function is to scramble the seed enough so the resulting seed is uniformly distributed across the long range (or something like that).

All we have to do is find an input to this function where it will produce an output of 0 to break things

A bit of brute forcing and I was able to find the long -9223372011639871891 , Using this long as an input, the function returns 0!

Now, we can define a random like the following:

var random = new Random(-9223372011639871891L);

The first call to random.nextInt() will always be zero, no matter the range! Initial calls to other random functions (nextDouble, nextFloat, etc.) will also produce VERY low values (but not exactly zero)

Of course, this all only applies to the first call to the "next" functions, but still cool regardless!

Volt4
  • 162
  • 6
  • Why do you consider getting a zero to be breaking things? Zero is one of the 2^32 valid outcomes from the generator, and is no weirder or broken than any other outcome. – pjs Aug 05 '22 at 21:56
  • @pjs Correct! Without any context there is nothing inherently problematic with this seed. 0 is totally a "possible" value and nothing is internally broken here. HOWEVER, when looking at an example like this with any context, issues can arise. Zeros can be inherently problematic when dealing with division, and given that with this seed, not only nextInt() will always be zero, but nextFloat() will be EXACTLY zero. The natural probability of something like this happening randomly is so low, most programmers probably wouldnt even check for these zeros, and in this case atypical behavior can arise. – Volt4 Aug 08 '22 at 13:33
  • So yes, definitely not broken, but I would say interesting or unusual for sure, which is what OP was asking. – Volt4 Aug 08 '22 at 14:02
  • Knowing that 0 is a valid outcome, any decent programmer shouldn't be doing raw division without a check. Similarly, `nextFloat()` produces values in the range [0,1), i.e., inclusive of the low end and exclusive of the upper end of the range. If the zero concerns you, you can always take `1.0 - result` to flip the inclusivity/exclusivity. The main argument I'm making is that 0 is an explicitly documented valid outcome, and occurs with the same probability as any other value in the documented range, so it's neither weird nor surprising and no more unusual than any other result. – pjs Aug 08 '22 at 14:05