blob: 3e3139e4990cc35fe099136be27c518338b9e94c [file] [log] [blame]
Raymond Hettinger40f62172002-12-29 23:03:38 +00001/* Random objects */
2
3/* ------------------------------------------------------------------
4 The code in this module was based on a download from:
Hiroki Nodaf15fa872017-02-15 18:04:43 +09005 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
Raymond Hettinger40f62172002-12-29 23:03:38 +00006
7 It was modified in 2002 by Raymond Hettinger as follows:
8
Benjamin Petersond8e5f2d2010-08-24 18:08:22 +00009 * the principal computational lines untouched.
Raymond Hettinger40f62172002-12-29 23:03:38 +000010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000011 * renamed genrand_res53() to random_random() and wrapped
12 in python calling/return code.
Raymond Hettinger40f62172002-12-29 23:03:38 +000013
Victor Stinner9f5fe792020-04-17 19:05:35 +020014 * genrand_uint32() and the helper functions, init_genrand()
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000015 and init_by_array(), were declared static, wrapped in
16 Python calling/return code. also, their global data
17 references were replaced with structure references.
Raymond Hettinger40f62172002-12-29 23:03:38 +000018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000019 * unused functions from the original were deleted.
20 new, original C python code was added to implement the
21 Random() interface.
Raymond Hettinger40f62172002-12-29 23:03:38 +000022
23 The following are the verbatim comments from the original code:
24
25 A C-program for MT19937, with initialization improved 2002/1/26.
26 Coded by Takuji Nishimura and Makoto Matsumoto.
27
28 Before using, initialize the state by using init_genrand(seed)
29 or init_by_array(init_key, key_length).
30
31 Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
32 All rights reserved.
33
34 Redistribution and use in source and binary forms, with or without
35 modification, are permitted provided that the following conditions
36 are met:
37
38 1. Redistributions of source code must retain the above copyright
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000039 notice, this list of conditions and the following disclaimer.
Raymond Hettinger40f62172002-12-29 23:03:38 +000040
41 2. Redistributions in binary form must reproduce the above copyright
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042 notice, this list of conditions and the following disclaimer in the
43 documentation and/or other materials provided with the distribution.
Raymond Hettinger40f62172002-12-29 23:03:38 +000044
45 3. The names of its contributors may not be used to endorse or promote
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 products derived from this software without specific prior written
47 permission.
Raymond Hettinger40f62172002-12-29 23:03:38 +000048
49 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
52 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
53 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
54 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
55 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
56 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
57 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
58 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60
61
62 Any feedback is very welcome.
Hiroki Nodaf15fa872017-02-15 18:04:43 +090063 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
64 email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
Raymond Hettinger40f62172002-12-29 23:03:38 +000065*/
66
67/* ---------------------------------------------------------------*/
68
69#include "Python.h"
Victor Stinner9f2a9202016-09-06 17:03:03 -070070#ifdef HAVE_PROCESS_H
Victor Stinner9f5fe792020-04-17 19:05:35 +020071# include <process.h> // getpid()
Victor Stinner9f2a9202016-09-06 17:03:03 -070072#endif
Raymond Hettinger40f62172002-12-29 23:03:38 +000073
74/* Period parameters -- These are all magic. Don't change. */
75#define N 624
76#define M 397
Serhiy Storchakadce04052015-05-13 15:02:12 +030077#define MATRIX_A 0x9908b0dfU /* constant vector a */
78#define UPPER_MASK 0x80000000U /* most significant w-r bits */
79#define LOWER_MASK 0x7fffffffU /* least significant r bits */
Raymond Hettinger40f62172002-12-29 23:03:38 +000080
81typedef struct {
Dino Viehland04f0bbf2019-09-13 11:12:27 +010082 PyObject *Random_Type;
83 PyObject *Long___abs__;
84} _randomstate;
85
Hai Shif707d942020-03-16 21:15:01 +080086static inline _randomstate*
87get_random_state(PyObject *module)
88{
89 void *state = PyModule_GetState(module);
90 assert(state != NULL);
91 return (_randomstate *)state;
92}
Dino Viehland04f0bbf2019-09-13 11:12:27 +010093
94static struct PyModuleDef _randommodule;
95
Hai Shif707d942020-03-16 21:15:01 +080096#define _randomstate_global get_random_state(PyState_FindModule(&_randommodule))
Dino Viehland04f0bbf2019-09-13 11:12:27 +010097
98typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 PyObject_HEAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 int index;
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700101 uint32_t state[N];
Raymond Hettinger40f62172002-12-29 23:03:38 +0000102} RandomObject;
103
Raymond Hettinger40f62172002-12-29 23:03:38 +0000104
Pablo Galindo561612d2019-05-24 22:09:23 +0100105#include "clinic/_randommodule.c.h"
106
107/*[clinic input]
108module _random
109class _random.Random "RandomObject *" "&Random_Type"
110[clinic start generated code]*/
111/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f79898ae7847c321]*/
Raymond Hettinger40f62172002-12-29 23:03:38 +0000112
113/* Random methods */
114
115
116/* generates a random number on [0,0xffffffff]-interval */
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700117static uint32_t
Victor Stinner9f5fe792020-04-17 19:05:35 +0200118genrand_uint32(RandomObject *self)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000119{
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700120 uint32_t y;
121 static const uint32_t mag01[2] = {0x0U, MATRIX_A};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 /* mag01[x] = x * MATRIX_A for x=0,1 */
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700123 uint32_t *mt;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 mt = self->state;
126 if (self->index >= N) { /* generate N words at one time */
127 int kk;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 for (kk=0;kk<N-M;kk++) {
130 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
Serhiy Storchakadce04052015-05-13 15:02:12 +0300131 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1U];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 }
133 for (;kk<N-1;kk++) {
134 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
Serhiy Storchakadce04052015-05-13 15:02:12 +0300135 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1U];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 }
137 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
Serhiy Storchakadce04052015-05-13 15:02:12 +0300138 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1U];
Raymond Hettinger40f62172002-12-29 23:03:38 +0000139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 self->index = 0;
141 }
Raymond Hettinger40f62172002-12-29 23:03:38 +0000142
143 y = mt[self->index++];
144 y ^= (y >> 11);
Serhiy Storchakadce04052015-05-13 15:02:12 +0300145 y ^= (y << 7) & 0x9d2c5680U;
146 y ^= (y << 15) & 0xefc60000U;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000147 y ^= (y >> 18);
148 return y;
149}
150
151/* random_random is the function named genrand_res53 in the original code;
152 * generates a random number on [0,1) with 53-bit resolution; note that
153 * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as
154 * multiply-by-reciprocal in the (likely vain) hope that the compiler will
155 * optimize the division away at compile-time. 67108864 is 2**26. In
156 * effect, a contains 27 random bits shifted left 26, and b fills in the
157 * lower 26 bits of the 53-bit numerator.
Berker Peksag0ac70c02016-04-29 16:54:10 +0300158 * The original code credited Isaku Wada for this algorithm, 2002/01/09.
Raymond Hettinger40f62172002-12-29 23:03:38 +0000159 */
Pablo Galindo561612d2019-05-24 22:09:23 +0100160
161/*[clinic input]
162_random.Random.random
163
164 self: self(type="RandomObject *")
165
166random() -> x in the interval [0, 1).
167[clinic start generated code]*/
168
Raymond Hettinger40f62172002-12-29 23:03:38 +0000169static PyObject *
Pablo Galindo561612d2019-05-24 22:09:23 +0100170_random_Random_random_impl(RandomObject *self)
171/*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/
Raymond Hettinger40f62172002-12-29 23:03:38 +0000172{
Victor Stinner9f5fe792020-04-17 19:05:35 +0200173 uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));
Raymond Hettinger40f62172002-12-29 23:03:38 +0000175}
176
177/* initializes mt[N] with a seed */
178static void
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700179init_genrand(RandomObject *self, uint32_t s)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 int mti;
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700182 uint32_t *mt;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 mt = self->state;
Serhiy Storchakadce04052015-05-13 15:02:12 +0300185 mt[0]= s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 for (mti=1; mti<N; mti++) {
187 mt[mti] =
Serhiy Storchakadce04052015-05-13 15:02:12 +0300188 (1812433253U * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
190 /* In the previous versions, MSBs of the seed affect */
191 /* only MSBs of the array mt[]. */
192 /* 2002/01/09 modified by Makoto Matsumoto */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 }
194 self->index = mti;
195 return;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000196}
197
198/* initialize by an array with array-length */
199/* init_key is the array for initializing keys */
200/* key_length is its length */
Victor Stinnere66987e2016-09-06 16:33:52 -0700201static void
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700202init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000203{
Mark Dickinson4cd60172012-12-21 21:52:49 +0000204 size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700205 uint32_t *mt;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 mt = self->state;
Serhiy Storchakadce04052015-05-13 15:02:12 +0300208 init_genrand(self, 19650218U);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 i=1; j=0;
210 k = (N>key_length ? N : key_length);
211 for (; k; k--) {
Serhiy Storchakadce04052015-05-13 15:02:12 +0300212 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U))
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700213 + init_key[j] + (uint32_t)j; /* non linear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 i++; j++;
215 if (i>=N) { mt[0] = mt[N-1]; i=1; }
216 if (j>=key_length) j=0;
217 }
218 for (k=N-1; k; k--) {
Serhiy Storchakadce04052015-05-13 15:02:12 +0300219 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U))
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700220 - (uint32_t)i; /* non linear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 i++;
222 if (i>=N) { mt[0] = mt[N-1]; i=1; }
223 }
Raymond Hettinger40f62172002-12-29 23:03:38 +0000224
Serhiy Storchakadce04052015-05-13 15:02:12 +0300225 mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
Raymond Hettinger40f62172002-12-29 23:03:38 +0000226}
227
228/*
229 * The rest is Python-specific code, neither part of, nor derived from, the
230 * Twister download.
231 */
232
Victor Stinnere66987e2016-09-06 16:33:52 -0700233static int
234random_seed_urandom(RandomObject *self)
235{
Victor Stinner1a1bd2e2020-04-17 19:13:06 +0200236 uint32_t key[N];
Victor Stinnere66987e2016-09-06 16:33:52 -0700237
238 if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) {
239 return -1;
240 }
241 init_by_array(self, key, Py_ARRAY_LENGTH(key));
242 return 0;
243}
244
245static void
246random_seed_time_pid(RandomObject *self)
247{
248 _PyTime_t now;
249 uint32_t key[5];
250
251 now = _PyTime_GetSystemClock();
Victor Stinner1a1bd2e2020-04-17 19:13:06 +0200252 key[0] = (uint32_t)(now & 0xffffffffU);
253 key[1] = (uint32_t)(now >> 32);
Victor Stinnere66987e2016-09-06 16:33:52 -0700254
Victor Stinner1a1bd2e2020-04-17 19:13:06 +0200255 key[2] = (uint32_t)getpid();
Victor Stinnere66987e2016-09-06 16:33:52 -0700256
257 now = _PyTime_GetMonotonicClock();
Victor Stinner1a1bd2e2020-04-17 19:13:06 +0200258 key[3] = (uint32_t)(now & 0xffffffffU);
259 key[4] = (uint32_t)(now >> 32);
Victor Stinnere66987e2016-09-06 16:33:52 -0700260
261 init_by_array(self, key, Py_ARRAY_LENGTH(key));
262}
263
Raymond Hettinger40f62172002-12-29 23:03:38 +0000264static PyObject *
Pablo Galindo561612d2019-05-24 22:09:23 +0100265random_seed(RandomObject *self, PyObject *arg)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 PyObject *result = NULL; /* guilty until proved innocent */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 PyObject *n = NULL;
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700269 uint32_t *key = NULL;
Serhiy Storchakadce04052015-05-13 15:02:12 +0300270 size_t bits, keyused;
Mark Dickinson4cd60172012-12-21 21:52:49 +0000271 int res;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000272
Pablo Galindo561612d2019-05-24 22:09:23 +0100273 if (arg == NULL || arg == Py_None) {
274 if (random_seed_urandom(self) < 0) {
Victor Stinnere66987e2016-09-06 16:33:52 -0700275 PyErr_Clear();
Raymond Hettinger40f62172002-12-29 23:03:38 +0000276
Victor Stinnere66987e2016-09-06 16:33:52 -0700277 /* Reading system entropy failed, fall back on the worst entropy:
278 use the current time and process identifier. */
279 random_seed_time_pid(self);
280 }
281 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 }
Victor Stinnere66987e2016-09-06 16:33:52 -0700283
Larry Hastingsd60cd422012-06-24 02:52:21 -0700284 /* This algorithm relies on the number being unsigned.
285 * So: if the arg is a PyLong, use its absolute value.
286 * Otherwise use its hash value, cast to unsigned.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 */
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100288 if (PyLong_CheckExact(arg)) {
289 n = PyNumber_Absolute(arg);
290 } else if (PyLong_Check(arg)) {
Oren Milmand780b2d2017-09-28 10:50:01 +0300291 /* Calling int.__abs__() prevents calling arg.__abs__(), which might
292 return an invalid value. See issue #31478. */
Victor Stinner00d7cd82020-03-10 15:15:14 +0100293 n = PyObject_CallOneArg(_randomstate_global->Long___abs__, arg);
Oren Milmand780b2d2017-09-28 10:50:01 +0300294 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 else {
Larry Hastingsd60cd422012-06-24 02:52:21 -0700296 Py_hash_t hash = PyObject_Hash(arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 if (hash == -1)
298 goto Done;
Larry Hastingsd60cd422012-06-24 02:52:21 -0700299 n = PyLong_FromSize_t((size_t)hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 }
301 if (n == NULL)
302 goto Done;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000303
Mark Dickinson4cd60172012-12-21 21:52:49 +0000304 /* Now split n into 32-bit chunks, from the right. */
305 bits = _PyLong_NumBits(n);
306 if (bits == (size_t)-1 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 goto Done;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000308
Mark Dickinson4cd60172012-12-21 21:52:49 +0000309 /* Figure out how many 32-bit chunks this gives us. */
310 keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000311
Mark Dickinson4cd60172012-12-21 21:52:49 +0000312 /* Convert seed to byte sequence. */
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700313 key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused);
Serhiy Storchakadce04052015-05-13 15:02:12 +0300314 if (key == NULL) {
Victor Stinnera4ced862013-07-15 20:00:36 +0200315 PyErr_NoMemory();
Mark Dickinson4cd60172012-12-21 21:52:49 +0000316 goto Done;
Victor Stinnera4ced862013-07-15 20:00:36 +0200317 }
Mark Dickinson4cd60172012-12-21 21:52:49 +0000318 res = _PyLong_AsByteArray((PyLongObject *)n,
Serhiy Storchakadce04052015-05-13 15:02:12 +0300319 (unsigned char *)key, keyused * 4,
320 PY_LITTLE_ENDIAN,
Mark Dickinson4cd60172012-12-21 21:52:49 +0000321 0); /* unsigned */
322 if (res == -1) {
Mark Dickinson4cd60172012-12-21 21:52:49 +0000323 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 }
Raymond Hettinger40f62172002-12-29 23:03:38 +0000325
Serhiy Storchakadce04052015-05-13 15:02:12 +0300326#if PY_BIG_ENDIAN
327 {
328 size_t i, j;
329 /* Reverse an array. */
Zachary Warec15ea4c2015-05-17 23:46:22 -0500330 for (i = 0, j = keyused - 1; i < j; i++, j--) {
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700331 uint32_t tmp = key[i];
Serhiy Storchakadce04052015-05-13 15:02:12 +0300332 key[i] = key[j];
333 key[j] = tmp;
334 }
Mark Dickinson4cd60172012-12-21 21:52:49 +0000335 }
Serhiy Storchakadce04052015-05-13 15:02:12 +0300336#endif
Victor Stinnere66987e2016-09-06 16:33:52 -0700337 init_by_array(self, key, keyused);
338
339 Py_INCREF(Py_None);
340 result = Py_None;
341
Raymond Hettinger40f62172002-12-29 23:03:38 +0000342Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 Py_XDECREF(n);
344 PyMem_Free(key);
345 return result;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000346}
347
Pablo Galindo561612d2019-05-24 22:09:23 +0100348/*[clinic input]
349_random.Random.seed
350
351 self: self(type="RandomObject *")
352 n: object = None
353 /
354
355seed([n]) -> None.
356
357Defaults to use urandom and falls back to a combination
358of the current time and the process identifier.
359[clinic start generated code]*/
360
Raymond Hettinger40f62172002-12-29 23:03:38 +0000361static PyObject *
Pablo Galindo561612d2019-05-24 22:09:23 +0100362_random_Random_seed_impl(RandomObject *self, PyObject *n)
363/*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/
364{
365 return random_seed(self, n);
366}
367
368/*[clinic input]
369_random.Random.getstate
370
371 self: self(type="RandomObject *")
372
373getstate() -> tuple containing the current state.
374[clinic start generated code]*/
375
376static PyObject *
377_random_Random_getstate_impl(RandomObject *self)
378/*[clinic end generated code: output=bf6cef0c092c7180 input=b937a487928c0e89]*/
Raymond Hettinger40f62172002-12-29 23:03:38 +0000379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 PyObject *state;
381 PyObject *element;
382 int i;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 state = PyTuple_New(N+1);
385 if (state == NULL)
386 return NULL;
387 for (i=0; i<N ; i++) {
388 element = PyLong_FromUnsignedLong(self->state[i]);
389 if (element == NULL)
390 goto Fail;
391 PyTuple_SET_ITEM(state, i, element);
392 }
393 element = PyLong_FromLong((long)(self->index));
394 if (element == NULL)
395 goto Fail;
396 PyTuple_SET_ITEM(state, i, element);
397 return state;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000398
399Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 Py_DECREF(state);
401 return NULL;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000402}
403
Pablo Galindo561612d2019-05-24 22:09:23 +0100404
405/*[clinic input]
406_random.Random.setstate
407
408 self: self(type="RandomObject *")
409 state: object
410 /
411
412setstate(state) -> None. Restores generator state.
413[clinic start generated code]*/
414
Raymond Hettinger40f62172002-12-29 23:03:38 +0000415static PyObject *
Pablo Galindo561612d2019-05-24 22:09:23 +0100416_random_Random_setstate(RandomObject *self, PyObject *state)
417/*[clinic end generated code: output=fd1c3cd0037b6681 input=b3b4efbb1bc66af8]*/
Raymond Hettinger40f62172002-12-29 23:03:38 +0000418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 int i;
420 unsigned long element;
421 long index;
bladebryan9616a822017-04-21 23:10:46 -0700422 uint32_t new_state[N];
Raymond Hettinger40f62172002-12-29 23:03:38 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 if (!PyTuple_Check(state)) {
425 PyErr_SetString(PyExc_TypeError,
426 "state vector must be a tuple");
427 return NULL;
428 }
429 if (PyTuple_Size(state) != N+1) {
430 PyErr_SetString(PyExc_ValueError,
431 "state vector is the wrong size");
432 return NULL;
433 }
Raymond Hettinger40f62172002-12-29 23:03:38 +0000434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 for (i=0; i<N ; i++) {
436 element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
437 if (element == (unsigned long)-1 && PyErr_Occurred())
438 return NULL;
bladebryan9616a822017-04-21 23:10:46 -0700439 new_state[i] = (uint32_t)element;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 }
Raymond Hettinger40f62172002-12-29 23:03:38 +0000441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
443 if (index == -1 && PyErr_Occurred())
444 return NULL;
Serhiy Storchaka178f0b62015-07-24 09:02:53 +0300445 if (index < 0 || index > N) {
446 PyErr_SetString(PyExc_ValueError, "invalid state");
447 return NULL;
448 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 self->index = (int)index;
bladebryan9616a822017-04-21 23:10:46 -0700450 for (i = 0; i < N; i++)
451 self->state[i] = new_state[i];
Raymond Hettinger40f62172002-12-29 23:03:38 +0000452
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200453 Py_RETURN_NONE;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000454}
455
Pablo Galindo561612d2019-05-24 22:09:23 +0100456/*[clinic input]
457
458_random.Random.getrandbits
459
460 self: self(type="RandomObject *")
461 k: int
462 /
463
464getrandbits(k) -> x. Generates an int with k random bits.
465[clinic start generated code]*/
466
Raymond Hettinger40f62172002-12-29 23:03:38 +0000467static PyObject *
Pablo Galindo561612d2019-05-24 22:09:23 +0100468_random_Random_getrandbits_impl(RandomObject *self, int k)
469/*[clinic end generated code: output=b402f82a2158887f input=8c0e6396dd176fc0]*/
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000470{
Pablo Galindo561612d2019-05-24 22:09:23 +0100471 int i, words;
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700472 uint32_t r;
473 uint32_t *wordarray;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 PyObject *result;
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000475
Antoine Pitrou75a33782020-04-17 19:32:14 +0200476 if (k < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 PyErr_SetString(PyExc_ValueError,
Antoine Pitrou75a33782020-04-17 19:32:14 +0200478 "number of bits must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 return NULL;
480 }
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000481
Antoine Pitrou75a33782020-04-17 19:32:14 +0200482 if (k == 0)
483 return PyLong_FromLong(0);
484
Serhiy Storchakad8a0bac2013-01-04 12:18:35 +0200485 if (k <= 32) /* Fast path */
Victor Stinner9f5fe792020-04-17 19:05:35 +0200486 return PyLong_FromUnsignedLong(genrand_uint32(self) >> (32 - k));
Serhiy Storchakad8a0bac2013-01-04 12:18:35 +0200487
Serhiy Storchakadce04052015-05-13 15:02:12 +0300488 words = (k - 1) / 32 + 1;
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700489 wordarray = (uint32_t *)PyMem_Malloc(words * 4);
Serhiy Storchakadce04052015-05-13 15:02:12 +0300490 if (wordarray == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 PyErr_NoMemory();
492 return NULL;
493 }
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000494
Serhiy Storchakadce04052015-05-13 15:02:12 +0300495 /* Fill-out bits of long integer, by 32-bit words, from least significant
496 to most significant. */
497#if PY_LITTLE_ENDIAN
498 for (i = 0; i < words; i++, k -= 32)
499#else
500 for (i = words - 1; i >= 0; i--, k -= 32)
501#endif
502 {
Victor Stinner9f5fe792020-04-17 19:05:35 +0200503 r = genrand_uint32(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if (k < 32)
Serhiy Storchakadce04052015-05-13 15:02:12 +0300505 r >>= (32 - k); /* Drop least significant bits */
506 wordarray[i] = r;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 }
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000508
Serhiy Storchakadce04052015-05-13 15:02:12 +0300509 result = _PyLong_FromByteArray((unsigned char *)wordarray, words * 4,
510 PY_LITTLE_ENDIAN, 0 /* unsigned */);
511 PyMem_Free(wordarray);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 return result;
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000513}
514
515static PyObject *
Raymond Hettinger40f62172002-12-29 23:03:38 +0000516random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 RandomObject *self;
519 PyObject *tmp;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000520
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100521 if (type == (PyTypeObject*)_randomstate_global->Random_Type &&
522 !_PyArg_NoKeywords("Random()", kwds)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 return NULL;
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100524 }
Georg Brandl02c42872005-08-26 06:42:30 +0000525
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100526 self = (RandomObject *)PyType_GenericAlloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 if (self == NULL)
528 return NULL;
529 tmp = random_seed(self, args);
530 if (tmp == NULL) {
531 Py_DECREF(self);
532 return NULL;
533 }
534 Py_DECREF(tmp);
535 return (PyObject *)self;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000536}
537
538static PyMethodDef random_methods[] = {
Pablo Galindo561612d2019-05-24 22:09:23 +0100539 _RANDOM_RANDOM_RANDOM_METHODDEF
540 _RANDOM_RANDOM_SEED_METHODDEF
541 _RANDOM_RANDOM_GETSTATE_METHODDEF
542 _RANDOM_RANDOM_SETSTATE_METHODDEF
543 _RANDOM_RANDOM_GETRANDBITS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 {NULL, NULL} /* sentinel */
Raymond Hettinger40f62172002-12-29 23:03:38 +0000545};
546
547PyDoc_STRVAR(random_doc,
548"Random() -> create a random number generator with its own internal state.");
549
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100550static PyType_Slot Random_Type_slots[] = {
Victor Stinner2f902612019-10-01 12:45:52 +0200551 {Py_tp_doc, (void *)random_doc},
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100552 {Py_tp_methods, random_methods},
553 {Py_tp_new, random_new},
554 {Py_tp_free, PyObject_Free},
555 {0, 0},
556};
557
558static PyType_Spec Random_Type_spec = {
559 "_random.Random",
560 sizeof(RandomObject),
561 0,
562 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
563 Random_Type_slots
Raymond Hettinger40f62172002-12-29 23:03:38 +0000564};
565
566PyDoc_STRVAR(module_doc,
567"Module implements the Mersenne Twister random number generator.");
568
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100569static int
570_random_traverse(PyObject *module, visitproc visit, void *arg)
571{
Hai Shif707d942020-03-16 21:15:01 +0800572 Py_VISIT(get_random_state(module)->Random_Type);
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100573 return 0;
574}
575
576static int
577_random_clear(PyObject *module)
578{
Hai Shif707d942020-03-16 21:15:01 +0800579 Py_CLEAR(get_random_state(module)->Random_Type);
580 Py_CLEAR(get_random_state(module)->Long___abs__);
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100581 return 0;
582}
583
584static void
585_random_free(void *module)
586{
587 _random_clear((PyObject *)module);
588}
Martin v. Löwis1a214512008-06-11 05:26:20 +0000589
590static struct PyModuleDef _randommodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 PyModuleDef_HEAD_INIT,
592 "_random",
593 module_doc,
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100594 sizeof(_randomstate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 NULL,
596 NULL,
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100597 _random_traverse,
598 _random_clear,
599 _random_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +0000600};
601
Raymond Hettinger40f62172002-12-29 23:03:38 +0000602PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000603PyInit__random(void)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000604{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 PyObject *m;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000606
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100607 PyObject *Random_Type = PyType_FromSpec(&Random_Type_spec);
608 if (Random_Type == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 return NULL;
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100610 }
611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 m = PyModule_Create(&_randommodule);
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100613 if (m == NULL) {
614 Py_DECREF(Random_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 return NULL;
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100616 }
Hai Shif707d942020-03-16 21:15:01 +0800617 get_random_state(m)->Random_Type = Random_Type;
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100618
619 Py_INCREF(Random_Type);
620 PyModule_AddObject(m, "Random", Random_Type);
621
622 /* Look up and save int.__abs__, which is needed in random_seed(). */
623 PyObject *longval = NULL, *longtype = NULL;
624 longval = PyLong_FromLong(0);
625 if (longval == NULL) goto fail;
626
627 longtype = PyObject_Type(longval);
628 if (longtype == NULL) goto fail;
629
630 PyObject *abs = PyObject_GetAttrString(longtype, "__abs__");
631 if (abs == NULL) goto fail;
632
633 Py_DECREF(longtype);
634 Py_DECREF(longval);
Hai Shif707d942020-03-16 21:15:01 +0800635 get_random_state(m)->Long___abs__ = abs;
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 return m;
Dino Viehland04f0bbf2019-09-13 11:12:27 +0100638
639fail:
640 Py_XDECREF(longtype);
641 Py_XDECREF(longval);
642 Py_DECREF(m);
643 return NULL;
Raymond Hettinger40f62172002-12-29 23:03:38 +0000644}