/** * Tiny Mersenne Twister: only 127-bit internal state. * Derived from the reference implementation version 1.1 (2015/04/24) * by Mutsuo Saito (Hiroshima University) and Makoto Matsumoto * (Hiroshima University). */ #include <stdint.h> /** * tinymt32 internal state vector and parameters */ typedef struct { uint32_t status[4]; uint32_t mat1; uint32_t mat2; uint32_t tmat; } tinymt32_t; static void tinymt32_next_state (tinymt32_t* s); static uint32_t tinymt32_temper (tinymt32_t* s); /** * Parameter set to use for this IETF specification. Don't change. * This parameter set is the first entry of the precalculated * parameter sets in tinymt32dc/tinymt32dc.0.1048576.txt by * Kenji Rikitake, available at: * https://github.com/jj1bdx/tinymtdc-longbatch/. * It is also the parameter set used in: * Rikitake, K., "TinyMT pseudo random number generator for * Erlang", Proceedings of the 11th ACM SIGPLAN Erlang Workshop, * September 2012. */ const uint32_t TINYMT32_MAT1_PARAM = UINT32_C(0x8f7011ee); const uint32_t TINYMT32_MAT2_PARAM = UINT32_C(0xfc78ff1f); const uint32_t TINYMT32_TMAT_PARAM = UINT32_C(0x3793fdff); /** * This function initializes the internal state array with a * 32-bit unsigned integer seed. * @param s pointer to tinymt internal state. * @param seed a 32-bit unsigned integer used as a seed. */ void tinymt32_init (tinymt32_t* s, uint32_t seed) { const uint32_t MIN_LOOP = 8; const uint32_t PRE_LOOP = 8; s->status[0] = seed; s->status[1] = s->mat1 = TINYMT32_MAT1_PARAM; s->status[2] = s->mat2 = TINYMT32_MAT2_PARAM; s->status[3] = s->tmat = TINYMT32_TMAT_PARAM; for (int i = 1; i < MIN_LOOP; i++) { s->status[i & 3] ^= i + UINT32_C(1812433253) * (s->status[(i - 1) & 3] ^ (s->status[(i - 1) & 3] >> 30)); } /* * NB: The parameter set of this specification warrants * that none of the possible 2^^32 seeds leads to an * all-zero 127-bit internal state. Therefore, the * period_certification() function of the original * TinyMT32 source code has been safely removed. If * another parameter set is used, this function will * have to be reintroduced here. */ for (int i = 0; i < PRE_LOOP; i++) { tinymt32_next_state(s); } } /** * This function outputs a 32-bit unsigned integer from * the internal state. * @param s pointer to tinymt internal state. * @return 32-bit unsigned integer r (0 <= r < 2^32). */ uint32_t tinymt32_generate_uint32 (tinymt32_t* s) { tinymt32_next_state(s); return tinymt32_temper(s); } /** * Internal tinymt32 constants and functions. * Users should not call these functions directly. */ const uint32_t TINYMT32_SH0 = 1; const uint32_t TINYMT32_SH1 = 10; const uint32_t TINYMT32_SH8 = 8; const uint32_t TINYMT32_MASK = UINT32_C(0x7fffffff); /** * This function changes the internal state of tinymt32. * @param s pointer to tinymt internal state. */ static void tinymt32_next_state (tinymt32_t* s) { uint32_t x; uint32_t y; y = s->status[3]; x = (s->status[0] & TINYMT32_MASK) ^ s->status[1] ^ s->status[2]; x ^= (x << TINYMT32_SH0); y ^= (y >> TINYMT32_SH0) ^ x; s->status[0] = s->status[1]; s->status[1] = s->status[2]; s->status[2] = x ^ (y << TINYMT32_SH1); s->status[3] = y; /* * The if (y & 1) {...} block below replaces: * s->status[1] ^= -((int32_t)(y & 1)) & s->mat1; * s->status[2] ^= -((int32_t)(y & 1)) & s->mat2; * The adopted code is equivalent to the original code * but does not depend on the representation of negative * integers by 2's complements. It is therefore more * portable but includes an if branch, which may slow * down the generation speed. */ if (y & 1) { s->status[1] ^= s->mat1; s->status[2] ^= s->mat2; } } /** * This function outputs a 32-bit unsigned integer from * the internal state. * @param s pointer to tinymt internal state. * @return 32-bit unsigned pseudorandom number. */ static uint32_t tinymt32_temper (tinymt32_t* s) { uint32_t t0, t1; t0 = s->status[3]; t1 = s->status[0] + (s->status[2] >> TINYMT32_SH8); t0 ^= t1; /* * The if (t1 & 1) {...} block below replaces: * t0 ^= -((int32_t)(t1 & 1)) & s->tmat; * The adopted code is equivalent to the original code * but does not depend on the representation of negative * integers by 2's complements. It is therefore more * portable but includes an if branch, which may slow * down the generation speed. */ if (t1 & 1) { t0 ^= s->tmat; } return t0; }
2545341989 981918433 3715302833 2387538352 3591001365 3820442102 2114400566 2196103051 2783359912 764534509 643179475 1822416315 881558334 4207026366 3690273640 3240535687 2921447122 3984931427 4092394160 44209675 2188315343 2908663843 1834519336 3774670961 3019990707 4065554902 1239765502 4035716197 3412127188 552822483 161364450 353727785 140085994 149132008 2547770827 4064042525 4078297538 2057335507 622384752 2041665899 2193913817 1080849512 33160901 662956935 642999063 3384709977 1723175122 3866752252 521822317 2292524454