Skip to content

Instantly share code, notes, and snippets.

@futuresecurity
Created August 22, 2019 20:46
Show Gist options
  • Save futuresecurity/63543c4f06a7ec2012df055fa083a9aa to your computer and use it in GitHub Desktop.
Save futuresecurity/63543c4f06a7ec2012df055fa083a9aa to your computer and use it in GitHub Desktop.
How to deterministically initalize a PRNG from (x, y) coordinates.
/* How to deterministically initalize a PRNG from (x, y) coordinates. The
* exact algorithm choice is arbitrary. `coordToLong` could be even simpler.
* The "hash" is a good scrambling function from 64-bit input to 64-bit
* output. Hashing might be redundant for certain PRNG implementations, but
* only if the implementation already mixes seeds very well. (Similar seeds
* can produce outputs with the same patterns.) If you use another RNG then
* you need to bundle its source with your project. C's "srand" should not
* be used because the same seed can produce different results on different
* platforms.
*/
public static long coordToLong(int x, int y)
{
// Co-prime and odd multipliers
return 0xf218258a20f6e313L * x + 0xa9d346a13008a355L * y;
}
public static long hash(long n)
{
// Better magic numbers from David Stafford
n ^= n >>> 31;
n *= 0x7fb5d329728ea185L;
n ^= n >>> 37;
n *= 0x81dadef4bc2dd44dL;
n ^= n >>> 33;
return n;
}
public static SplittableRandom getSeededRng(int x, int y)
{
long n = coordToLong(x, y);
return new SplittableRandom(n);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment