17db96d56Sopenharmony_ci/* Random objects */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci/* ------------------------------------------------------------------ 47db96d56Sopenharmony_ci The code in this module was based on a download from: 57db96d56Sopenharmony_ci http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci It was modified in 2002 by Raymond Hettinger as follows: 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci * the principal computational lines untouched. 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci * renamed genrand_res53() to random_random() and wrapped 127db96d56Sopenharmony_ci in python calling/return code. 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci * genrand_uint32() and the helper functions, init_genrand() 157db96d56Sopenharmony_ci and init_by_array(), were declared static, wrapped in 167db96d56Sopenharmony_ci Python calling/return code. also, their global data 177db96d56Sopenharmony_ci references were replaced with structure references. 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci * unused functions from the original were deleted. 207db96d56Sopenharmony_ci new, original C python code was added to implement the 217db96d56Sopenharmony_ci Random() interface. 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci The following are the verbatim comments from the original code: 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci A C-program for MT19937, with initialization improved 2002/1/26. 267db96d56Sopenharmony_ci Coded by Takuji Nishimura and Makoto Matsumoto. 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci Before using, initialize the state by using init_genrand(seed) 297db96d56Sopenharmony_ci or init_by_array(init_key, key_length). 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 327db96d56Sopenharmony_ci All rights reserved. 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci Redistribution and use in source and binary forms, with or without 357db96d56Sopenharmony_ci modification, are permitted provided that the following conditions 367db96d56Sopenharmony_ci are met: 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ci 1. Redistributions of source code must retain the above copyright 397db96d56Sopenharmony_ci notice, this list of conditions and the following disclaimer. 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci 2. Redistributions in binary form must reproduce the above copyright 427db96d56Sopenharmony_ci notice, this list of conditions and the following disclaimer in the 437db96d56Sopenharmony_ci documentation and/or other materials provided with the distribution. 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci 3. The names of its contributors may not be used to endorse or promote 467db96d56Sopenharmony_ci products derived from this software without specific prior written 477db96d56Sopenharmony_ci permission. 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 507db96d56Sopenharmony_ci "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 517db96d56Sopenharmony_ci LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 527db96d56Sopenharmony_ci A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 537db96d56Sopenharmony_ci CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 547db96d56Sopenharmony_ci EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 557db96d56Sopenharmony_ci PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 567db96d56Sopenharmony_ci PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 577db96d56Sopenharmony_ci LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 587db96d56Sopenharmony_ci NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 597db96d56Sopenharmony_ci SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci Any feedback is very welcome. 637db96d56Sopenharmony_ci http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html 647db96d56Sopenharmony_ci email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) 657db96d56Sopenharmony_ci*/ 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci/* ---------------------------------------------------------------*/ 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE_BUILTIN 707db96d56Sopenharmony_ci# define Py_BUILD_CORE_MODULE 1 717db96d56Sopenharmony_ci#endif 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci#include "Python.h" 747db96d56Sopenharmony_ci#include "pycore_moduleobject.h" // _PyModule_GetState() 757db96d56Sopenharmony_ci#ifdef HAVE_PROCESS_H 767db96d56Sopenharmony_ci# include <process.h> // getpid() 777db96d56Sopenharmony_ci#endif 787db96d56Sopenharmony_ci 797db96d56Sopenharmony_ci/* Period parameters -- These are all magic. Don't change. */ 807db96d56Sopenharmony_ci#define N 624 817db96d56Sopenharmony_ci#define M 397 827db96d56Sopenharmony_ci#define MATRIX_A 0x9908b0dfU /* constant vector a */ 837db96d56Sopenharmony_ci#define UPPER_MASK 0x80000000U /* most significant w-r bits */ 847db96d56Sopenharmony_ci#define LOWER_MASK 0x7fffffffU /* least significant r bits */ 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_citypedef struct { 877db96d56Sopenharmony_ci PyObject *Random_Type; 887db96d56Sopenharmony_ci PyObject *Long___abs__; 897db96d56Sopenharmony_ci} _randomstate; 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_cistatic inline _randomstate* 927db96d56Sopenharmony_ciget_random_state(PyObject *module) 937db96d56Sopenharmony_ci{ 947db96d56Sopenharmony_ci void *state = _PyModule_GetState(module); 957db96d56Sopenharmony_ci assert(state != NULL); 967db96d56Sopenharmony_ci return (_randomstate *)state; 977db96d56Sopenharmony_ci} 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_cistatic struct PyModuleDef _randommodule; 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci#define _randomstate_type(type) \ 1027db96d56Sopenharmony_ci (get_random_state(PyType_GetModuleByDef(type, &_randommodule))) 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_citypedef struct { 1057db96d56Sopenharmony_ci PyObject_HEAD 1067db96d56Sopenharmony_ci int index; 1077db96d56Sopenharmony_ci uint32_t state[N]; 1087db96d56Sopenharmony_ci} RandomObject; 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_ci#include "clinic/_randommodule.c.h" 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ci/*[clinic input] 1147db96d56Sopenharmony_cimodule _random 1157db96d56Sopenharmony_ciclass _random.Random "RandomObject *" "_randomstate_type(type)->Random_Type" 1167db96d56Sopenharmony_ci[clinic start generated code]*/ 1177db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70a2c99619474983]*/ 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci/* Random methods */ 1207db96d56Sopenharmony_ci 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci/* generates a random number on [0,0xffffffff]-interval */ 1237db96d56Sopenharmony_cistatic uint32_t 1247db96d56Sopenharmony_cigenrand_uint32(RandomObject *self) 1257db96d56Sopenharmony_ci{ 1267db96d56Sopenharmony_ci uint32_t y; 1277db96d56Sopenharmony_ci static const uint32_t mag01[2] = {0x0U, MATRIX_A}; 1287db96d56Sopenharmony_ci /* mag01[x] = x * MATRIX_A for x=0,1 */ 1297db96d56Sopenharmony_ci uint32_t *mt; 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ci mt = self->state; 1327db96d56Sopenharmony_ci if (self->index >= N) { /* generate N words at one time */ 1337db96d56Sopenharmony_ci int kk; 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ci for (kk=0;kk<N-M;kk++) { 1367db96d56Sopenharmony_ci y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); 1377db96d56Sopenharmony_ci mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1U]; 1387db96d56Sopenharmony_ci } 1397db96d56Sopenharmony_ci for (;kk<N-1;kk++) { 1407db96d56Sopenharmony_ci y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); 1417db96d56Sopenharmony_ci mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1U]; 1427db96d56Sopenharmony_ci } 1437db96d56Sopenharmony_ci y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); 1447db96d56Sopenharmony_ci mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1U]; 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ci self->index = 0; 1477db96d56Sopenharmony_ci } 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci y = mt[self->index++]; 1507db96d56Sopenharmony_ci y ^= (y >> 11); 1517db96d56Sopenharmony_ci y ^= (y << 7) & 0x9d2c5680U; 1527db96d56Sopenharmony_ci y ^= (y << 15) & 0xefc60000U; 1537db96d56Sopenharmony_ci y ^= (y >> 18); 1547db96d56Sopenharmony_ci return y; 1557db96d56Sopenharmony_ci} 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci/* random_random is the function named genrand_res53 in the original code; 1587db96d56Sopenharmony_ci * generates a random number on [0,1) with 53-bit resolution; note that 1597db96d56Sopenharmony_ci * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as 1607db96d56Sopenharmony_ci * multiply-by-reciprocal in the (likely vain) hope that the compiler will 1617db96d56Sopenharmony_ci * optimize the division away at compile-time. 67108864 is 2**26. In 1627db96d56Sopenharmony_ci * effect, a contains 27 random bits shifted left 26, and b fills in the 1637db96d56Sopenharmony_ci * lower 26 bits of the 53-bit numerator. 1647db96d56Sopenharmony_ci * The original code credited Isaku Wada for this algorithm, 2002/01/09. 1657db96d56Sopenharmony_ci */ 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci/*[clinic input] 1687db96d56Sopenharmony_ci_random.Random.random 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci self: self(type="RandomObject *") 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_cirandom() -> x in the interval [0, 1). 1737db96d56Sopenharmony_ci[clinic start generated code]*/ 1747db96d56Sopenharmony_ci 1757db96d56Sopenharmony_cistatic PyObject * 1767db96d56Sopenharmony_ci_random_Random_random_impl(RandomObject *self) 1777db96d56Sopenharmony_ci/*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/ 1787db96d56Sopenharmony_ci{ 1797db96d56Sopenharmony_ci uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6; 1807db96d56Sopenharmony_ci return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); 1817db96d56Sopenharmony_ci} 1827db96d56Sopenharmony_ci 1837db96d56Sopenharmony_ci/* initializes mt[N] with a seed */ 1847db96d56Sopenharmony_cistatic void 1857db96d56Sopenharmony_ciinit_genrand(RandomObject *self, uint32_t s) 1867db96d56Sopenharmony_ci{ 1877db96d56Sopenharmony_ci int mti; 1887db96d56Sopenharmony_ci uint32_t *mt; 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_ci mt = self->state; 1917db96d56Sopenharmony_ci mt[0]= s; 1927db96d56Sopenharmony_ci for (mti=1; mti<N; mti++) { 1937db96d56Sopenharmony_ci mt[mti] = 1947db96d56Sopenharmony_ci (1812433253U * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 1957db96d56Sopenharmony_ci /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ 1967db96d56Sopenharmony_ci /* In the previous versions, MSBs of the seed affect */ 1977db96d56Sopenharmony_ci /* only MSBs of the array mt[]. */ 1987db96d56Sopenharmony_ci /* 2002/01/09 modified by Makoto Matsumoto */ 1997db96d56Sopenharmony_ci } 2007db96d56Sopenharmony_ci self->index = mti; 2017db96d56Sopenharmony_ci return; 2027db96d56Sopenharmony_ci} 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci/* initialize by an array with array-length */ 2057db96d56Sopenharmony_ci/* init_key is the array for initializing keys */ 2067db96d56Sopenharmony_ci/* key_length is its length */ 2077db96d56Sopenharmony_cistatic void 2087db96d56Sopenharmony_ciinit_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) 2097db96d56Sopenharmony_ci{ 2107db96d56Sopenharmony_ci size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ 2117db96d56Sopenharmony_ci uint32_t *mt; 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci mt = self->state; 2147db96d56Sopenharmony_ci init_genrand(self, 19650218U); 2157db96d56Sopenharmony_ci i=1; j=0; 2167db96d56Sopenharmony_ci k = (N>key_length ? N : key_length); 2177db96d56Sopenharmony_ci for (; k; k--) { 2187db96d56Sopenharmony_ci mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U)) 2197db96d56Sopenharmony_ci + init_key[j] + (uint32_t)j; /* non linear */ 2207db96d56Sopenharmony_ci i++; j++; 2217db96d56Sopenharmony_ci if (i>=N) { mt[0] = mt[N-1]; i=1; } 2227db96d56Sopenharmony_ci if (j>=key_length) j=0; 2237db96d56Sopenharmony_ci } 2247db96d56Sopenharmony_ci for (k=N-1; k; k--) { 2257db96d56Sopenharmony_ci mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U)) 2267db96d56Sopenharmony_ci - (uint32_t)i; /* non linear */ 2277db96d56Sopenharmony_ci i++; 2287db96d56Sopenharmony_ci if (i>=N) { mt[0] = mt[N-1]; i=1; } 2297db96d56Sopenharmony_ci } 2307db96d56Sopenharmony_ci 2317db96d56Sopenharmony_ci mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ 2327db96d56Sopenharmony_ci} 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ci/* 2357db96d56Sopenharmony_ci * The rest is Python-specific code, neither part of, nor derived from, the 2367db96d56Sopenharmony_ci * Twister download. 2377db96d56Sopenharmony_ci */ 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_cistatic int 2407db96d56Sopenharmony_cirandom_seed_urandom(RandomObject *self) 2417db96d56Sopenharmony_ci{ 2427db96d56Sopenharmony_ci uint32_t key[N]; 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) { 2457db96d56Sopenharmony_ci return -1; 2467db96d56Sopenharmony_ci } 2477db96d56Sopenharmony_ci init_by_array(self, key, Py_ARRAY_LENGTH(key)); 2487db96d56Sopenharmony_ci return 0; 2497db96d56Sopenharmony_ci} 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_cistatic void 2527db96d56Sopenharmony_cirandom_seed_time_pid(RandomObject *self) 2537db96d56Sopenharmony_ci{ 2547db96d56Sopenharmony_ci _PyTime_t now; 2557db96d56Sopenharmony_ci uint32_t key[5]; 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci now = _PyTime_GetSystemClock(); 2587db96d56Sopenharmony_ci key[0] = (uint32_t)(now & 0xffffffffU); 2597db96d56Sopenharmony_ci key[1] = (uint32_t)(now >> 32); 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ci#ifdef HAVE_GETPID 2627db96d56Sopenharmony_ci key[2] = (uint32_t)getpid(); 2637db96d56Sopenharmony_ci#else 2647db96d56Sopenharmony_ci key[2] = 0; 2657db96d56Sopenharmony_ci#endif 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci now = _PyTime_GetMonotonicClock(); 2687db96d56Sopenharmony_ci key[3] = (uint32_t)(now & 0xffffffffU); 2697db96d56Sopenharmony_ci key[4] = (uint32_t)(now >> 32); 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci init_by_array(self, key, Py_ARRAY_LENGTH(key)); 2727db96d56Sopenharmony_ci} 2737db96d56Sopenharmony_ci 2747db96d56Sopenharmony_cistatic int 2757db96d56Sopenharmony_cirandom_seed(RandomObject *self, PyObject *arg) 2767db96d56Sopenharmony_ci{ 2777db96d56Sopenharmony_ci int result = -1; /* guilty until proved innocent */ 2787db96d56Sopenharmony_ci PyObject *n = NULL; 2797db96d56Sopenharmony_ci uint32_t *key = NULL; 2807db96d56Sopenharmony_ci size_t bits, keyused; 2817db96d56Sopenharmony_ci int res; 2827db96d56Sopenharmony_ci 2837db96d56Sopenharmony_ci if (arg == NULL || arg == Py_None) { 2847db96d56Sopenharmony_ci if (random_seed_urandom(self) < 0) { 2857db96d56Sopenharmony_ci PyErr_Clear(); 2867db96d56Sopenharmony_ci 2877db96d56Sopenharmony_ci /* Reading system entropy failed, fall back on the worst entropy: 2887db96d56Sopenharmony_ci use the current time and process identifier. */ 2897db96d56Sopenharmony_ci random_seed_time_pid(self); 2907db96d56Sopenharmony_ci } 2917db96d56Sopenharmony_ci return 0; 2927db96d56Sopenharmony_ci } 2937db96d56Sopenharmony_ci 2947db96d56Sopenharmony_ci /* This algorithm relies on the number being unsigned. 2957db96d56Sopenharmony_ci * So: if the arg is a PyLong, use its absolute value. 2967db96d56Sopenharmony_ci * Otherwise use its hash value, cast to unsigned. 2977db96d56Sopenharmony_ci */ 2987db96d56Sopenharmony_ci if (PyLong_CheckExact(arg)) { 2997db96d56Sopenharmony_ci n = PyNumber_Absolute(arg); 3007db96d56Sopenharmony_ci } else if (PyLong_Check(arg)) { 3017db96d56Sopenharmony_ci /* Calling int.__abs__() prevents calling arg.__abs__(), which might 3027db96d56Sopenharmony_ci return an invalid value. See issue #31478. */ 3037db96d56Sopenharmony_ci _randomstate *state = _randomstate_type(Py_TYPE(self)); 3047db96d56Sopenharmony_ci n = PyObject_CallOneArg(state->Long___abs__, arg); 3057db96d56Sopenharmony_ci } 3067db96d56Sopenharmony_ci else { 3077db96d56Sopenharmony_ci Py_hash_t hash = PyObject_Hash(arg); 3087db96d56Sopenharmony_ci if (hash == -1) 3097db96d56Sopenharmony_ci goto Done; 3107db96d56Sopenharmony_ci n = PyLong_FromSize_t((size_t)hash); 3117db96d56Sopenharmony_ci } 3127db96d56Sopenharmony_ci if (n == NULL) 3137db96d56Sopenharmony_ci goto Done; 3147db96d56Sopenharmony_ci 3157db96d56Sopenharmony_ci /* Now split n into 32-bit chunks, from the right. */ 3167db96d56Sopenharmony_ci bits = _PyLong_NumBits(n); 3177db96d56Sopenharmony_ci if (bits == (size_t)-1 && PyErr_Occurred()) 3187db96d56Sopenharmony_ci goto Done; 3197db96d56Sopenharmony_ci 3207db96d56Sopenharmony_ci /* Figure out how many 32-bit chunks this gives us. */ 3217db96d56Sopenharmony_ci keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1; 3227db96d56Sopenharmony_ci 3237db96d56Sopenharmony_ci /* Convert seed to byte sequence. */ 3247db96d56Sopenharmony_ci key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused); 3257db96d56Sopenharmony_ci if (key == NULL) { 3267db96d56Sopenharmony_ci PyErr_NoMemory(); 3277db96d56Sopenharmony_ci goto Done; 3287db96d56Sopenharmony_ci } 3297db96d56Sopenharmony_ci res = _PyLong_AsByteArray((PyLongObject *)n, 3307db96d56Sopenharmony_ci (unsigned char *)key, keyused * 4, 3317db96d56Sopenharmony_ci PY_LITTLE_ENDIAN, 3327db96d56Sopenharmony_ci 0); /* unsigned */ 3337db96d56Sopenharmony_ci if (res == -1) { 3347db96d56Sopenharmony_ci goto Done; 3357db96d56Sopenharmony_ci } 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ci#if PY_BIG_ENDIAN 3387db96d56Sopenharmony_ci { 3397db96d56Sopenharmony_ci size_t i, j; 3407db96d56Sopenharmony_ci /* Reverse an array. */ 3417db96d56Sopenharmony_ci for (i = 0, j = keyused - 1; i < j; i++, j--) { 3427db96d56Sopenharmony_ci uint32_t tmp = key[i]; 3437db96d56Sopenharmony_ci key[i] = key[j]; 3447db96d56Sopenharmony_ci key[j] = tmp; 3457db96d56Sopenharmony_ci } 3467db96d56Sopenharmony_ci } 3477db96d56Sopenharmony_ci#endif 3487db96d56Sopenharmony_ci init_by_array(self, key, keyused); 3497db96d56Sopenharmony_ci 3507db96d56Sopenharmony_ci result = 0; 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ciDone: 3537db96d56Sopenharmony_ci Py_XDECREF(n); 3547db96d56Sopenharmony_ci PyMem_Free(key); 3557db96d56Sopenharmony_ci return result; 3567db96d56Sopenharmony_ci} 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ci/*[clinic input] 3597db96d56Sopenharmony_ci_random.Random.seed 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ci self: self(type="RandomObject *") 3627db96d56Sopenharmony_ci n: object = None 3637db96d56Sopenharmony_ci / 3647db96d56Sopenharmony_ci 3657db96d56Sopenharmony_ciseed([n]) -> None. 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ciDefaults to use urandom and falls back to a combination 3687db96d56Sopenharmony_ciof the current time and the process identifier. 3697db96d56Sopenharmony_ci[clinic start generated code]*/ 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_cistatic PyObject * 3727db96d56Sopenharmony_ci_random_Random_seed_impl(RandomObject *self, PyObject *n) 3737db96d56Sopenharmony_ci/*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/ 3747db96d56Sopenharmony_ci{ 3757db96d56Sopenharmony_ci if (random_seed(self, n) < 0) { 3767db96d56Sopenharmony_ci return NULL; 3777db96d56Sopenharmony_ci } 3787db96d56Sopenharmony_ci Py_RETURN_NONE; 3797db96d56Sopenharmony_ci} 3807db96d56Sopenharmony_ci 3817db96d56Sopenharmony_ci/*[clinic input] 3827db96d56Sopenharmony_ci_random.Random.getstate 3837db96d56Sopenharmony_ci 3847db96d56Sopenharmony_ci self: self(type="RandomObject *") 3857db96d56Sopenharmony_ci 3867db96d56Sopenharmony_cigetstate() -> tuple containing the current state. 3877db96d56Sopenharmony_ci[clinic start generated code]*/ 3887db96d56Sopenharmony_ci 3897db96d56Sopenharmony_cistatic PyObject * 3907db96d56Sopenharmony_ci_random_Random_getstate_impl(RandomObject *self) 3917db96d56Sopenharmony_ci/*[clinic end generated code: output=bf6cef0c092c7180 input=b937a487928c0e89]*/ 3927db96d56Sopenharmony_ci{ 3937db96d56Sopenharmony_ci PyObject *state; 3947db96d56Sopenharmony_ci PyObject *element; 3957db96d56Sopenharmony_ci int i; 3967db96d56Sopenharmony_ci 3977db96d56Sopenharmony_ci state = PyTuple_New(N+1); 3987db96d56Sopenharmony_ci if (state == NULL) 3997db96d56Sopenharmony_ci return NULL; 4007db96d56Sopenharmony_ci for (i=0; i<N ; i++) { 4017db96d56Sopenharmony_ci element = PyLong_FromUnsignedLong(self->state[i]); 4027db96d56Sopenharmony_ci if (element == NULL) 4037db96d56Sopenharmony_ci goto Fail; 4047db96d56Sopenharmony_ci PyTuple_SET_ITEM(state, i, element); 4057db96d56Sopenharmony_ci } 4067db96d56Sopenharmony_ci element = PyLong_FromLong((long)(self->index)); 4077db96d56Sopenharmony_ci if (element == NULL) 4087db96d56Sopenharmony_ci goto Fail; 4097db96d56Sopenharmony_ci PyTuple_SET_ITEM(state, i, element); 4107db96d56Sopenharmony_ci return state; 4117db96d56Sopenharmony_ci 4127db96d56Sopenharmony_ciFail: 4137db96d56Sopenharmony_ci Py_DECREF(state); 4147db96d56Sopenharmony_ci return NULL; 4157db96d56Sopenharmony_ci} 4167db96d56Sopenharmony_ci 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_ci/*[clinic input] 4197db96d56Sopenharmony_ci_random.Random.setstate 4207db96d56Sopenharmony_ci 4217db96d56Sopenharmony_ci self: self(type="RandomObject *") 4227db96d56Sopenharmony_ci state: object 4237db96d56Sopenharmony_ci / 4247db96d56Sopenharmony_ci 4257db96d56Sopenharmony_cisetstate(state) -> None. Restores generator state. 4267db96d56Sopenharmony_ci[clinic start generated code]*/ 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_cistatic PyObject * 4297db96d56Sopenharmony_ci_random_Random_setstate(RandomObject *self, PyObject *state) 4307db96d56Sopenharmony_ci/*[clinic end generated code: output=fd1c3cd0037b6681 input=b3b4efbb1bc66af8]*/ 4317db96d56Sopenharmony_ci{ 4327db96d56Sopenharmony_ci int i; 4337db96d56Sopenharmony_ci unsigned long element; 4347db96d56Sopenharmony_ci long index; 4357db96d56Sopenharmony_ci uint32_t new_state[N]; 4367db96d56Sopenharmony_ci 4377db96d56Sopenharmony_ci if (!PyTuple_Check(state)) { 4387db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 4397db96d56Sopenharmony_ci "state vector must be a tuple"); 4407db96d56Sopenharmony_ci return NULL; 4417db96d56Sopenharmony_ci } 4427db96d56Sopenharmony_ci if (PyTuple_Size(state) != N+1) { 4437db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 4447db96d56Sopenharmony_ci "state vector is the wrong size"); 4457db96d56Sopenharmony_ci return NULL; 4467db96d56Sopenharmony_ci } 4477db96d56Sopenharmony_ci 4487db96d56Sopenharmony_ci for (i=0; i<N ; i++) { 4497db96d56Sopenharmony_ci element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i)); 4507db96d56Sopenharmony_ci if (element == (unsigned long)-1 && PyErr_Occurred()) 4517db96d56Sopenharmony_ci return NULL; 4527db96d56Sopenharmony_ci new_state[i] = (uint32_t)element; 4537db96d56Sopenharmony_ci } 4547db96d56Sopenharmony_ci 4557db96d56Sopenharmony_ci index = PyLong_AsLong(PyTuple_GET_ITEM(state, i)); 4567db96d56Sopenharmony_ci if (index == -1 && PyErr_Occurred()) 4577db96d56Sopenharmony_ci return NULL; 4587db96d56Sopenharmony_ci if (index < 0 || index > N) { 4597db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "invalid state"); 4607db96d56Sopenharmony_ci return NULL; 4617db96d56Sopenharmony_ci } 4627db96d56Sopenharmony_ci self->index = (int)index; 4637db96d56Sopenharmony_ci for (i = 0; i < N; i++) 4647db96d56Sopenharmony_ci self->state[i] = new_state[i]; 4657db96d56Sopenharmony_ci 4667db96d56Sopenharmony_ci Py_RETURN_NONE; 4677db96d56Sopenharmony_ci} 4687db96d56Sopenharmony_ci 4697db96d56Sopenharmony_ci/*[clinic input] 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci_random.Random.getrandbits 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ci self: self(type="RandomObject *") 4747db96d56Sopenharmony_ci k: int 4757db96d56Sopenharmony_ci / 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_cigetrandbits(k) -> x. Generates an int with k random bits. 4787db96d56Sopenharmony_ci[clinic start generated code]*/ 4797db96d56Sopenharmony_ci 4807db96d56Sopenharmony_cistatic PyObject * 4817db96d56Sopenharmony_ci_random_Random_getrandbits_impl(RandomObject *self, int k) 4827db96d56Sopenharmony_ci/*[clinic end generated code: output=b402f82a2158887f input=8c0e6396dd176fc0]*/ 4837db96d56Sopenharmony_ci{ 4847db96d56Sopenharmony_ci int i, words; 4857db96d56Sopenharmony_ci uint32_t r; 4867db96d56Sopenharmony_ci uint32_t *wordarray; 4877db96d56Sopenharmony_ci PyObject *result; 4887db96d56Sopenharmony_ci 4897db96d56Sopenharmony_ci if (k < 0) { 4907db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 4917db96d56Sopenharmony_ci "number of bits must be non-negative"); 4927db96d56Sopenharmony_ci return NULL; 4937db96d56Sopenharmony_ci } 4947db96d56Sopenharmony_ci 4957db96d56Sopenharmony_ci if (k == 0) 4967db96d56Sopenharmony_ci return PyLong_FromLong(0); 4977db96d56Sopenharmony_ci 4987db96d56Sopenharmony_ci if (k <= 32) /* Fast path */ 4997db96d56Sopenharmony_ci return PyLong_FromUnsignedLong(genrand_uint32(self) >> (32 - k)); 5007db96d56Sopenharmony_ci 5017db96d56Sopenharmony_ci words = (k - 1) / 32 + 1; 5027db96d56Sopenharmony_ci wordarray = (uint32_t *)PyMem_Malloc(words * 4); 5037db96d56Sopenharmony_ci if (wordarray == NULL) { 5047db96d56Sopenharmony_ci PyErr_NoMemory(); 5057db96d56Sopenharmony_ci return NULL; 5067db96d56Sopenharmony_ci } 5077db96d56Sopenharmony_ci 5087db96d56Sopenharmony_ci /* Fill-out bits of long integer, by 32-bit words, from least significant 5097db96d56Sopenharmony_ci to most significant. */ 5107db96d56Sopenharmony_ci#if PY_LITTLE_ENDIAN 5117db96d56Sopenharmony_ci for (i = 0; i < words; i++, k -= 32) 5127db96d56Sopenharmony_ci#else 5137db96d56Sopenharmony_ci for (i = words - 1; i >= 0; i--, k -= 32) 5147db96d56Sopenharmony_ci#endif 5157db96d56Sopenharmony_ci { 5167db96d56Sopenharmony_ci r = genrand_uint32(self); 5177db96d56Sopenharmony_ci if (k < 32) 5187db96d56Sopenharmony_ci r >>= (32 - k); /* Drop least significant bits */ 5197db96d56Sopenharmony_ci wordarray[i] = r; 5207db96d56Sopenharmony_ci } 5217db96d56Sopenharmony_ci 5227db96d56Sopenharmony_ci result = _PyLong_FromByteArray((unsigned char *)wordarray, words * 4, 5237db96d56Sopenharmony_ci PY_LITTLE_ENDIAN, 0 /* unsigned */); 5247db96d56Sopenharmony_ci PyMem_Free(wordarray); 5257db96d56Sopenharmony_ci return result; 5267db96d56Sopenharmony_ci} 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_cistatic int 5297db96d56Sopenharmony_cirandom_init(RandomObject *self, PyObject *args, PyObject *kwds) 5307db96d56Sopenharmony_ci{ 5317db96d56Sopenharmony_ci PyObject *arg = NULL; 5327db96d56Sopenharmony_ci _randomstate *state = _randomstate_type(Py_TYPE(self)); 5337db96d56Sopenharmony_ci 5347db96d56Sopenharmony_ci if ((Py_IS_TYPE(self, (PyTypeObject *)state->Random_Type) || 5357db96d56Sopenharmony_ci Py_TYPE(self)->tp_init == ((PyTypeObject*)state->Random_Type)->tp_init) && 5367db96d56Sopenharmony_ci !_PyArg_NoKeywords("Random", kwds)) { 5377db96d56Sopenharmony_ci return -1; 5387db96d56Sopenharmony_ci } 5397db96d56Sopenharmony_ci 5407db96d56Sopenharmony_ci if (PyTuple_GET_SIZE(args) > 1) { 5417db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "Random() requires 0 or 1 argument"); 5427db96d56Sopenharmony_ci return -1; 5437db96d56Sopenharmony_ci } 5447db96d56Sopenharmony_ci 5457db96d56Sopenharmony_ci if (PyTuple_GET_SIZE(args) == 1) 5467db96d56Sopenharmony_ci arg = PyTuple_GET_ITEM(args, 0); 5477db96d56Sopenharmony_ci 5487db96d56Sopenharmony_ci return random_seed(self, arg); 5497db96d56Sopenharmony_ci} 5507db96d56Sopenharmony_ci 5517db96d56Sopenharmony_ci 5527db96d56Sopenharmony_cistatic PyMethodDef random_methods[] = { 5537db96d56Sopenharmony_ci _RANDOM_RANDOM_RANDOM_METHODDEF 5547db96d56Sopenharmony_ci _RANDOM_RANDOM_SEED_METHODDEF 5557db96d56Sopenharmony_ci _RANDOM_RANDOM_GETSTATE_METHODDEF 5567db96d56Sopenharmony_ci _RANDOM_RANDOM_SETSTATE_METHODDEF 5577db96d56Sopenharmony_ci _RANDOM_RANDOM_GETRANDBITS_METHODDEF 5587db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 5597db96d56Sopenharmony_ci}; 5607db96d56Sopenharmony_ci 5617db96d56Sopenharmony_ciPyDoc_STRVAR(random_doc, 5627db96d56Sopenharmony_ci"Random() -> create a random number generator with its own internal state."); 5637db96d56Sopenharmony_ci 5647db96d56Sopenharmony_cistatic PyType_Slot Random_Type_slots[] = { 5657db96d56Sopenharmony_ci {Py_tp_doc, (void *)random_doc}, 5667db96d56Sopenharmony_ci {Py_tp_methods, random_methods}, 5677db96d56Sopenharmony_ci {Py_tp_new, PyType_GenericNew}, 5687db96d56Sopenharmony_ci {Py_tp_init, random_init}, 5697db96d56Sopenharmony_ci {Py_tp_free, PyObject_Free}, 5707db96d56Sopenharmony_ci {0, 0}, 5717db96d56Sopenharmony_ci}; 5727db96d56Sopenharmony_ci 5737db96d56Sopenharmony_cistatic PyType_Spec Random_Type_spec = { 5747db96d56Sopenharmony_ci "_random.Random", 5757db96d56Sopenharmony_ci sizeof(RandomObject), 5767db96d56Sopenharmony_ci 0, 5777db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 5787db96d56Sopenharmony_ci Random_Type_slots 5797db96d56Sopenharmony_ci}; 5807db96d56Sopenharmony_ci 5817db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc, 5827db96d56Sopenharmony_ci"Module implements the Mersenne Twister random number generator."); 5837db96d56Sopenharmony_ci 5847db96d56Sopenharmony_cistatic int 5857db96d56Sopenharmony_ci_random_exec(PyObject *module) 5867db96d56Sopenharmony_ci{ 5877db96d56Sopenharmony_ci _randomstate *state = get_random_state(module); 5887db96d56Sopenharmony_ci 5897db96d56Sopenharmony_ci state->Random_Type = PyType_FromModuleAndSpec( 5907db96d56Sopenharmony_ci module, &Random_Type_spec, NULL); 5917db96d56Sopenharmony_ci if (state->Random_Type == NULL) { 5927db96d56Sopenharmony_ci return -1; 5937db96d56Sopenharmony_ci } 5947db96d56Sopenharmony_ci if (PyModule_AddType(module, (PyTypeObject *)state->Random_Type) < 0) { 5957db96d56Sopenharmony_ci return -1; 5967db96d56Sopenharmony_ci } 5977db96d56Sopenharmony_ci 5987db96d56Sopenharmony_ci /* Look up and save int.__abs__, which is needed in random_seed(). */ 5997db96d56Sopenharmony_ci PyObject *longval = PyLong_FromLong(0); 6007db96d56Sopenharmony_ci if (longval == NULL) { 6017db96d56Sopenharmony_ci return -1; 6027db96d56Sopenharmony_ci } 6037db96d56Sopenharmony_ci 6047db96d56Sopenharmony_ci PyObject *longtype = PyObject_Type(longval); 6057db96d56Sopenharmony_ci Py_DECREF(longval); 6067db96d56Sopenharmony_ci if (longtype == NULL) { 6077db96d56Sopenharmony_ci return -1; 6087db96d56Sopenharmony_ci } 6097db96d56Sopenharmony_ci 6107db96d56Sopenharmony_ci state->Long___abs__ = PyObject_GetAttrString(longtype, "__abs__"); 6117db96d56Sopenharmony_ci Py_DECREF(longtype); 6127db96d56Sopenharmony_ci if (state->Long___abs__ == NULL) { 6137db96d56Sopenharmony_ci return -1; 6147db96d56Sopenharmony_ci } 6157db96d56Sopenharmony_ci return 0; 6167db96d56Sopenharmony_ci} 6177db96d56Sopenharmony_ci 6187db96d56Sopenharmony_cistatic PyModuleDef_Slot _random_slots[] = { 6197db96d56Sopenharmony_ci {Py_mod_exec, _random_exec}, 6207db96d56Sopenharmony_ci {0, NULL} 6217db96d56Sopenharmony_ci}; 6227db96d56Sopenharmony_ci 6237db96d56Sopenharmony_cistatic int 6247db96d56Sopenharmony_ci_random_traverse(PyObject *module, visitproc visit, void *arg) 6257db96d56Sopenharmony_ci{ 6267db96d56Sopenharmony_ci Py_VISIT(get_random_state(module)->Random_Type); 6277db96d56Sopenharmony_ci return 0; 6287db96d56Sopenharmony_ci} 6297db96d56Sopenharmony_ci 6307db96d56Sopenharmony_cistatic int 6317db96d56Sopenharmony_ci_random_clear(PyObject *module) 6327db96d56Sopenharmony_ci{ 6337db96d56Sopenharmony_ci Py_CLEAR(get_random_state(module)->Random_Type); 6347db96d56Sopenharmony_ci Py_CLEAR(get_random_state(module)->Long___abs__); 6357db96d56Sopenharmony_ci return 0; 6367db96d56Sopenharmony_ci} 6377db96d56Sopenharmony_ci 6387db96d56Sopenharmony_cistatic void 6397db96d56Sopenharmony_ci_random_free(void *module) 6407db96d56Sopenharmony_ci{ 6417db96d56Sopenharmony_ci _random_clear((PyObject *)module); 6427db96d56Sopenharmony_ci} 6437db96d56Sopenharmony_ci 6447db96d56Sopenharmony_cistatic struct PyModuleDef _randommodule = { 6457db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 6467db96d56Sopenharmony_ci "_random", 6477db96d56Sopenharmony_ci module_doc, 6487db96d56Sopenharmony_ci sizeof(_randomstate), 6497db96d56Sopenharmony_ci NULL, 6507db96d56Sopenharmony_ci _random_slots, 6517db96d56Sopenharmony_ci _random_traverse, 6527db96d56Sopenharmony_ci _random_clear, 6537db96d56Sopenharmony_ci _random_free, 6547db96d56Sopenharmony_ci}; 6557db96d56Sopenharmony_ci 6567db96d56Sopenharmony_ciPyMODINIT_FUNC 6577db96d56Sopenharmony_ciPyInit__random(void) 6587db96d56Sopenharmony_ci{ 6597db96d56Sopenharmony_ci return PyModuleDef_Init(&_randommodule); 6607db96d56Sopenharmony_ci} 661