1/* Random objects */
2
3/* ------------------------------------------------------------------
4 The code in this module was based on a download from:
5 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
6
7 It was modified in 2002 by Raymond Hettinger as follows:
8
9 * the principal computational lines untouched.
10
11 * renamed genrand_res53() to random_random() and wrapped
12 in python calling/return code.
13
14 * genrand_uint32() and the helper functions, init_genrand()
15 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.
18
19 * unused functions from the original were deleted.
20 new, original C python code was added to implement the
21 Random() interface.
22
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
39 notice, this list of conditions and the following disclaimer.
40
41 2. Redistributions in binary form must reproduce the above copyright
42 notice, this list of conditions and the following disclaimer in the
43 documentation and/or other materials provided with the distribution.
44
45 3. The names of its contributors may not be used to endorse or promote
46 products derived from this software without specific prior written
47 permission.
48
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.
63 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)
65*/
66
67/* ---------------------------------------------------------------*/
68
69#include "Python.h"
70#include "pycore_moduleobject.h" // _PyModule_GetState()
71#ifdef HAVE_PROCESS_H
72# include <process.h> // getpid()
73#endif
74
75/* Period parameters -- These are all magic. Don't change. */
76#define N 624
77#define M 397
78#define MATRIX_A 0x9908b0dfU /* constant vector a */
79#define UPPER_MASK 0x80000000U /* most significant w-r bits */
80#define LOWER_MASK 0x7fffffffU /* least significant r bits */
81
82typedef struct {
83 PyObject *Random_Type;
84 PyObject *Long___abs__;
85} _randomstate;
86
87static inline _randomstate*
88get_random_state(PyObject *module)
89{
90 void *state = _PyModule_GetState(module);
91 assert(state != NULL);
92 return (_randomstate *)state;
93}
94
95static struct PyModuleDef _randommodule;
96
97#define _randomstate_type(type) \
98 (get_random_state(_PyType_GetModuleByDef(type, &_randommodule)))
99
100typedef struct {
101 PyObject_HEAD
102 int index;
103 uint32_t state[N];
104} RandomObject;
105
106
107#include "clinic/_randommodule.c.h"
108
109/*[clinic input]
110module _random
111class _random.Random "RandomObject *" "_randomstate_type(type)->Random_Type"
112[clinic start generated code]*/
113/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70a2c99619474983]*/
114
115/* Random methods */
116
117
118/* generates a random number on [0,0xffffffff]-interval */
119static uint32_t
120genrand_uint32(RandomObject *self)
121{
122 uint32_t y;
123 static const uint32_t mag01[2] = {0x0U, MATRIX_A};
124 /* mag01[x] = x * MATRIX_A for x=0,1 */
125 uint32_t *mt;
126
127 mt = self->state;
128 if (self->index >= N) { /* generate N words at one time */
129 int kk;
130
131 for (kk=0;kk<N-M;kk++) {
132 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
133 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1U];
134 }
135 for (;kk<N-1;kk++) {
136 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
137 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1U];
138 }
139 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
140 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1U];
141
142 self->index = 0;
143 }
144
145 y = mt[self->index++];
146 y ^= (y >> 11);
147 y ^= (y << 7) & 0x9d2c5680U;
148 y ^= (y << 15) & 0xefc60000U;
149 y ^= (y >> 18);
150 return y;
151}
152
153/* random_random is the function named genrand_res53 in the original code;
154 * generates a random number on [0,1) with 53-bit resolution; note that
155 * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as
156 * multiply-by-reciprocal in the (likely vain) hope that the compiler will
157 * optimize the division away at compile-time. 67108864 is 2**26. In
158 * effect, a contains 27 random bits shifted left 26, and b fills in the
159 * lower 26 bits of the 53-bit numerator.
160 * The original code credited Isaku Wada for this algorithm, 2002/01/09.
161 */
162
163/*[clinic input]
164_random.Random.random
165
166 self: self(type="RandomObject *")
167
168random() -> x in the interval [0, 1).
169[clinic start generated code]*/
170
171static PyObject *
172_random_Random_random_impl(RandomObject *self)
173/*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/
174{
175 uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6;
176 return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));
177}
178
179/* initializes mt[N] with a seed */
180static void
181init_genrand(RandomObject *self, uint32_t s)
182{
183 int mti;
184 uint32_t *mt;
185
186 mt = self->state;
187 mt[0]= s;
188 for (mti=1; mti<N; mti++) {
189 mt[mti] =
190 (1812433253U * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
191 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
192 /* In the previous versions, MSBs of the seed affect */
193 /* only MSBs of the array mt[]. */
194 /* 2002/01/09 modified by Makoto Matsumoto */
195 }
196 self->index = mti;
197 return;
198}
199
200/* initialize by an array with array-length */
201/* init_key is the array for initializing keys */
202/* key_length is its length */
203static void
204init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length)
205{
206 size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */
207 uint32_t *mt;
208
209 mt = self->state;
210 init_genrand(self, 19650218U);
211 i=1; j=0;
212 k = (N>key_length ? N : key_length);
213 for (; k; k--) {
214 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U))
215 + init_key[j] + (uint32_t)j; /* non linear */
216 i++; j++;
217 if (i>=N) { mt[0] = mt[N-1]; i=1; }
218 if (j>=key_length) j=0;
219 }
220 for (k=N-1; k; k--) {
221 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U))
222 - (uint32_t)i; /* non linear */
223 i++;
224 if (i>=N) { mt[0] = mt[N-1]; i=1; }
225 }
226
227 mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
228}
229
230/*
231 * The rest is Python-specific code, neither part of, nor derived from, the
232 * Twister download.
233 */
234
235static int
236random_seed_urandom(RandomObject *self)
237{
238 uint32_t key[N];
239
240 if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) {
241 return -1;
242 }
243 init_by_array(self, key, Py_ARRAY_LENGTH(key));
244 return 0;
245}
246
247static void
248random_seed_time_pid(RandomObject *self)
249{
250 _PyTime_t now;
251 uint32_t key[5];
252
253 now = _PyTime_GetSystemClock();
254 key[0] = (uint32_t)(now & 0xffffffffU);
255 key[1] = (uint32_t)(now >> 32);
256
257 key[2] = (uint32_t)getpid();
258
259 now = _PyTime_GetMonotonicClock();
260 key[3] = (uint32_t)(now & 0xffffffffU);
261 key[4] = (uint32_t)(now >> 32);
262
263 init_by_array(self, key, Py_ARRAY_LENGTH(key));
264}
265
266static PyObject *
267random_seed(RandomObject *self, PyObject *arg)
268{
269 PyObject *result = NULL; /* guilty until proved innocent */
270 PyObject *n = NULL;
271 uint32_t *key = NULL;
272 size_t bits, keyused;
273 int res;
274
275 if (arg == NULL || arg == Py_None) {
276 if (random_seed_urandom(self) < 0) {
277 PyErr_Clear();
278
279 /* Reading system entropy failed, fall back on the worst entropy:
280 use the current time and process identifier. */
281 random_seed_time_pid(self);
282 }
283 Py_RETURN_NONE;
284 }
285
286 /* This algorithm relies on the number being unsigned.
287 * So: if the arg is a PyLong, use its absolute value.
288 * Otherwise use its hash value, cast to unsigned.
289 */
290 if (PyLong_CheckExact(arg)) {
291 n = PyNumber_Absolute(arg);
292 } else if (PyLong_Check(arg)) {
293 /* Calling int.__abs__() prevents calling arg.__abs__(), which might
294 return an invalid value. See issue #31478. */
295 _randomstate *state = _randomstate_type(Py_TYPE(self));
296 n = PyObject_CallOneArg(state->Long___abs__, arg);
297 }
298 else {
299 Py_hash_t hash = PyObject_Hash(arg);
300 if (hash == -1)
301 goto Done;
302 n = PyLong_FromSize_t((size_t)hash);
303 }
304 if (n == NULL)
305 goto Done;
306
307 /* Now split n into 32-bit chunks, from the right. */
308 bits = _PyLong_NumBits(n);
309 if (bits == (size_t)-1 && PyErr_Occurred())
310 goto Done;
311
312 /* Figure out how many 32-bit chunks this gives us. */
313 keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1;
314
315 /* Convert seed to byte sequence. */
316 key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused);
317 if (key == NULL) {
318 PyErr_NoMemory();
319 goto Done;
320 }
321 res = _PyLong_AsByteArray((PyLongObject *)n,
322 (unsigned char *)key, keyused * 4,
323 PY_LITTLE_ENDIAN,
324 0); /* unsigned */
325 if (res == -1) {
326 goto Done;
327 }
328
329#if PY_BIG_ENDIAN
330 {
331 size_t i, j;
332 /* Reverse an array. */
333 for (i = 0, j = keyused - 1; i < j; i++, j--) {
334 uint32_t tmp = key[i];
335 key[i] = key[j];
336 key[j] = tmp;
337 }
338 }
339#endif
340 init_by_array(self, key, keyused);
341
342 Py_INCREF(Py_None);
343 result = Py_None;
344
345Done:
346 Py_XDECREF(n);
347 PyMem_Free(key);
348 return result;
349}
350
351/*[clinic input]
352_random.Random.seed
353
354 self: self(type="RandomObject *")
355 n: object = None
356 /
357
358seed([n]) -> None.
359
360Defaults to use urandom and falls back to a combination
361of the current time and the process identifier.
362[clinic start generated code]*/
363
364static PyObject *
365_random_Random_seed_impl(RandomObject *self, PyObject *n)
366/*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/
367{
368 return random_seed(self, n);
369}
370
371/*[clinic input]
372_random.Random.getstate
373
374 self: self(type="RandomObject *")
375
376getstate() -> tuple containing the current state.
377[clinic start generated code]*/
378
379static PyObject *
380_random_Random_getstate_impl(RandomObject *self)
381/*[clinic end generated code: output=bf6cef0c092c7180 input=b937a487928c0e89]*/
382{
383 PyObject *state;
384 PyObject *element;
385 int i;
386
387 state = PyTuple_New(N+1);
388 if (state == NULL)
389 return NULL;
390 for (i=0; i<N ; i++) {
391 element = PyLong_FromUnsignedLong(self->state[i]);
392 if (element == NULL)
393 goto Fail;
394 PyTuple_SET_ITEM(state, i, element);
395 }
396 element = PyLong_FromLong((long)(self->index));
397 if (element == NULL)
398 goto Fail;
399 PyTuple_SET_ITEM(state, i, element);
400 return state;
401
402Fail:
403 Py_DECREF(state);
404 return NULL;
405}
406
407
408/*[clinic input]
409_random.Random.setstate
410
411 self: self(type="RandomObject *")
412 state: object
413 /
414
415setstate(state) -> None. Restores generator state.
416[clinic start generated code]*/
417
418static PyObject *
419_random_Random_setstate(RandomObject *self, PyObject *state)
420/*[clinic end generated code: output=fd1c3cd0037b6681 input=b3b4efbb1bc66af8]*/
421{
422 int i;
423 unsigned long element;
424 long index;
425 uint32_t new_state[N];
426
427 if (!PyTuple_Check(state)) {
428 PyErr_SetString(PyExc_TypeError,
429 "state vector must be a tuple");
430 return NULL;
431 }
432 if (PyTuple_Size(state) != N+1) {
433 PyErr_SetString(PyExc_ValueError,
434 "state vector is the wrong size");
435 return NULL;
436 }
437
438 for (i=0; i<N ; i++) {
439 element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
440 if (element == (unsigned long)-1 && PyErr_Occurred())
441 return NULL;
442 new_state[i] = (uint32_t)element;
443 }
444
445 index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
446 if (index == -1 && PyErr_Occurred())
447 return NULL;
448 if (index < 0 || index > N) {
449 PyErr_SetString(PyExc_ValueError, "invalid state");
450 return NULL;
451 }
452 self->index = (int)index;
453 for (i = 0; i < N; i++)
454 self->state[i] = new_state[i];
455
456 Py_RETURN_NONE;
457}
458
459/*[clinic input]
460
461_random.Random.getrandbits
462
463 self: self(type="RandomObject *")
464 k: int
465 /
466
467getrandbits(k) -> x. Generates an int with k random bits.
468[clinic start generated code]*/
469
470static PyObject *
471_random_Random_getrandbits_impl(RandomObject *self, int k)
472/*[clinic end generated code: output=b402f82a2158887f input=8c0e6396dd176fc0]*/
473{
474 int i, words;
475 uint32_t r;
476 uint32_t *wordarray;
477 PyObject *result;
478
479 if (k < 0) {
480 PyErr_SetString(PyExc_ValueError,
481 "number of bits must be non-negative");
482 return NULL;
483 }
484
485 if (k == 0)
486 return PyLong_FromLong(0);
487
488 if (k <= 32) /* Fast path */
489 return PyLong_FromUnsignedLong(genrand_uint32(self) >> (32 - k));
490
491 words = (k - 1) / 32 + 1;
492 wordarray = (uint32_t *)PyMem_Malloc(words * 4);
493 if (wordarray == NULL) {
494 PyErr_NoMemory();
495 return NULL;
496 }
497
498 /* Fill-out bits of long integer, by 32-bit words, from least significant
499 to most significant. */
500#if PY_LITTLE_ENDIAN
501 for (i = 0; i < words; i++, k -= 32)
502#else
503 for (i = words - 1; i >= 0; i--, k -= 32)
504#endif
505 {
506 r = genrand_uint32(self);
507 if (k < 32)
508 r >>= (32 - k); /* Drop least significant bits */
509 wordarray[i] = r;
510 }
511
512 result = _PyLong_FromByteArray((unsigned char *)wordarray, words * 4,
513 PY_LITTLE_ENDIAN, 0 /* unsigned */);
514 PyMem_Free(wordarray);
515 return result;
516}
517
518static PyObject *
519random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
520{
521 RandomObject *self;
522 PyObject *tmp;
523 PyObject *arg = NULL;
524 _randomstate *state = _randomstate_type(type);
525
526 if (type == (PyTypeObject*)state->Random_Type &&
527 !_PyArg_NoKeywords("Random()", kwds)) {
528 return NULL;
529 }
530
531 self = (RandomObject *)PyType_GenericAlloc(type, 0);
532 if (self == NULL)
533 return NULL;
534
535 if (PyTuple_GET_SIZE(args) > 1) {
536 PyErr_SetString(PyExc_TypeError, "Random() requires 0 or 1 argument");
537 return NULL;
538 }
539
540 if (PyTuple_GET_SIZE(args) == 1)
541 arg = PyTuple_GET_ITEM(args, 0);
542
543 tmp = random_seed(self, arg);
544 if (tmp == NULL) {
545 Py_DECREF(self);
546 return NULL;
547 }
548 Py_DECREF(tmp);
549
550 return (PyObject *)self;
551}
552
553
554static PyMethodDef random_methods[] = {
555 _RANDOM_RANDOM_RANDOM_METHODDEF
556 _RANDOM_RANDOM_SEED_METHODDEF
557 _RANDOM_RANDOM_GETSTATE_METHODDEF
558 _RANDOM_RANDOM_SETSTATE_METHODDEF
559 _RANDOM_RANDOM_GETRANDBITS_METHODDEF
560 {NULL, NULL} /* sentinel */
561};
562
563PyDoc_STRVAR(random_doc,
564"Random() -> create a random number generator with its own internal state.");
565
566static PyType_Slot Random_Type_slots[] = {
567 {Py_tp_doc, (void *)random_doc},
568 {Py_tp_methods, random_methods},
569 {Py_tp_new, random_new},
570 {Py_tp_free, PyObject_Free},
571 {0, 0},
572};
573
574static PyType_Spec Random_Type_spec = {
575 "_random.Random",
576 sizeof(RandomObject),
577 0,
578 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
579 Random_Type_slots
580};
581
582PyDoc_STRVAR(module_doc,
583"Module implements the Mersenne Twister random number generator.");
584
585static int
586_random_exec(PyObject *module)
587{
588 _randomstate *state = get_random_state(module);
589
590 state->Random_Type = PyType_FromModuleAndSpec(
591 module, &Random_Type_spec, NULL);
592 if (state->Random_Type == NULL) {
593 return -1;
594 }
595 if (PyModule_AddType(module, (PyTypeObject *)state->Random_Type) < 0) {
596 return -1;
597 }
598
599 /* Look up and save int.__abs__, which is needed in random_seed(). */
600 PyObject *longval = PyLong_FromLong(0);
601 if (longval == NULL) {
602 return -1;
603 }
604
605 PyObject *longtype = PyObject_Type(longval);
606 Py_DECREF(longval);
607 if (longtype == NULL) {
608 return -1;
609 }
610
611 state->Long___abs__ = PyObject_GetAttrString(longtype, "__abs__");
612 Py_DECREF(longtype);
613 if (state->Long___abs__ == NULL) {
614 return -1;
615 }
616 return 0;
617}
618
619static PyModuleDef_Slot _random_slots[] = {
620 {Py_mod_exec, _random_exec},
621 {0, NULL}
622};
623
624static int
625_random_traverse(PyObject *module, visitproc visit, void *arg)
626{
627 Py_VISIT(get_random_state(module)->Random_Type);
628 return 0;
629}
630
631static int
632_random_clear(PyObject *module)
633{
634 Py_CLEAR(get_random_state(module)->Random_Type);
635 Py_CLEAR(get_random_state(module)->Long___abs__);
636 return 0;
637}
638
639static void
640_random_free(void *module)
641{
642 _random_clear((PyObject *)module);
643}
644
645static struct PyModuleDef _randommodule = {
646 PyModuleDef_HEAD_INIT,
647 "_random",
648 module_doc,
649 sizeof(_randomstate),
650 NULL,
651 _random_slots,
652 _random_traverse,
653 _random_clear,
654 _random_free,
655};
656
657PyMODINIT_FUNC
658PyInit__random(void)
659{
660 return PyModuleDef_Init(&_randommodule);
661}
662