Skip to content

Instantly share code, notes, and snippets.

@integeruser
Last active September 24, 2023 14:09
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save integeruser/4cca768836c68751904fe215c94e914c to your computer and use it in GitHub Desktop.
Save integeruser/4cca768836c68751904fe215c94e914c to your computer and use it in GitHub Desktop.
Python port of the GLIBC rng
#!/usr/bin/env python2
from ctypes import c_int, c_uint
# http://www.mscs.dal.ca/~selinger/random/
def srand(seed):
srand.r = [0 for _ in range(34)]
srand.r[0] = c_int(seed).value
for i in range(1, 31):
srand.r[i] = (16807 * srand.r[i - 1]) % 2147483647
for i in range(31, 34):
srand.r[i] = srand.r[i - 31]
srand.k = 0
for _ in range(34, 344):
rand()
def rand():
srand.r[srand.k] = srand.r[(srand.k - 31) % 34] + srand.r[(srand.k - 3) % 34]
r = c_uint(srand.r[srand.k]).value >> 1
srand.k = (srand.k + 1) % 34
return r
if __name__ == '__main__':
srand(1337)
assert [rand() for _ in range(10)] == [
292616681, 1638893262, 255706927, 995816787, 588263094, 1540293802, 343418821, 903681492,
898530248, 1459533395
]
srand(0xffffffff + 0xffffffff - 1)
assert [rand() for _ in range(10)] == [
853660264, 1568971201, 1203662233, 15207980, 1421679843, 1717493552, 811896681, 155106358,
1156099704, 428649477
]
srand(-1337)
assert [rand() for _ in range(10)] == [
1766598330, 413225925, 1792113474, 2120225281, 1445538174, 488114690, 1678701932,
1108308242, 32946609, 1612248994
]
srand(-0xffffffff - 0xffffffff)
assert [rand() for _ in range(10)] == [
1505335290, 1738766719, 190686788, 260874575, 747983061, 906156498, 1502820864, 142559277,
1261608745, 1380759627
]
# from ctypes import cdll
# from ctypes.util import find_library
# libc = cdll.LoadLibrary(find_library('c'))
# libc.srand(1337)
# print[libc.rand() for _ in range(10)]
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
srand(1337);
for (int i = 0; i < 10; ++i) {
printf("%d\n", rand());
}
printf("\n");
srand(0xffffffff + 0xffffffff - 1);
for (int i = 0; i < 10; ++i) {
printf("%d\n", rand());
}
printf("\n");
srand(-1337);
for (int i = 0; i < 10; ++i) {
printf("%d\n", rand());
}
printf("\n");
srand(-0xffffffff - 0xffffffff);
for (int i = 0; i < 10; ++i) {
printf("%d\n", rand());
}
return 0;
}
@stek29
Copy link

stek29 commented Apr 5, 2021

small correction: glibc srand algorithm breaks on seed==0, so it has following code in it:

/* We must make sure the seed is not 0.  Take arbitrarily 1 in this case.  */
if (seed == 0)
  seed = 1;

so srand(0) == srand(1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment