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