In case anyone needs to do this, I came up with a working version based on the CPython implementation here.
Note: If you seed with a string, random.seed()
changed between Python 2 and 3. The pythonStringHash
function here is compatible with the Python 2 version, or in Python 3, random.seed(s, version=1)
.
private static long pythonStringHash(String s) {
char[] chars = s.toCharArray();
long x;
if (s.isEmpty()) {
x = 0;
} else {
x = chars[0] << 7;
}
for (char c : chars) {
x = ((1000003 * x) ^ c);
}
x ^= chars.length;
if (x == -1) {
return -2;
}
return x;
}
private static void pythonSeed(MersenneTwister random, long seed) {
int[] intArray;
if (Long.numberOfLeadingZeros(seed) >= 32) {
intArray = new int[] { (int) seed };
} else {
intArray = new int[] { (int) seed, (int) (seed >> 32) };
}
random.setSeed(intArray);
}
public static RandomGenerator pythonSeededRandom(String seed) {
MersenneTwister random = new MersenneTwister();
pythonSeed(random, pythonStringHash(seed));
return random;
}
From there, pythonSeededRandom("foo").nextDouble()
should be equal to random.seed("foo"); random.random()
.