• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
82  typedef struct {
83      PyObject *Random_Type;
84      PyObject *Long___abs__;
85  } _randomstate;
86  
87  static inline _randomstate*
get_random_state(PyObject * module)88  get_random_state(PyObject *module)
89  {
90      void *state = _PyModule_GetState(module);
91      assert(state != NULL);
92      return (_randomstate *)state;
93  }
94  
95  static struct PyModuleDef _randommodule;
96  
97  #define _randomstate_type(type) \
98      (get_random_state(_PyType_GetModuleByDef(type, &_randommodule)))
99  
100  typedef 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]
110  module _random
111  class _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 */
119  static uint32_t
genrand_uint32(RandomObject * self)120  genrand_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  
168  random() -> x in the interval [0, 1).
169  [clinic start generated code]*/
170  
171  static PyObject *
_random_Random_random_impl(RandomObject * self)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 */
180  static void
init_genrand(RandomObject * self,uint32_t s)181  init_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 */
203  static void
init_by_array(RandomObject * self,uint32_t init_key[],size_t key_length)204  init_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  
235  static int
random_seed_urandom(RandomObject * self)236  random_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  
247  static void
random_seed_time_pid(RandomObject * self)248  random_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  
266  static PyObject *
random_seed(RandomObject * self,PyObject * arg)267  random_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  
345  Done:
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  
358  seed([n]) -> None.
359  
360  Defaults to use urandom and falls back to a combination
361  of the current time and the process identifier.
362  [clinic start generated code]*/
363  
364  static PyObject *
_random_Random_seed_impl(RandomObject * self,PyObject * n)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  
376  getstate() -> tuple containing the current state.
377  [clinic start generated code]*/
378  
379  static PyObject *
_random_Random_getstate_impl(RandomObject * self)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  
402  Fail:
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  
415  setstate(state) -> None.  Restores generator state.
416  [clinic start generated code]*/
417  
418  static PyObject *
_random_Random_setstate(RandomObject * self,PyObject * state)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  
467  getrandbits(k) -> x.  Generates an int with k random bits.
468  [clinic start generated code]*/
469  
470  static PyObject *
_random_Random_getrandbits_impl(RandomObject * self,int k)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  
518  static PyObject *
random_new(PyTypeObject * type,PyObject * args,PyObject * kwds)519  random_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  
554  static 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  
563  PyDoc_STRVAR(random_doc,
564  "Random() -> create a random number generator with its own internal state.");
565  
566  static 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  
574  static 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  
582  PyDoc_STRVAR(module_doc,
583  "Module implements the Mersenne Twister random number generator.");
584  
585  static int
_random_exec(PyObject * module)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  
619  static PyModuleDef_Slot _random_slots[] = {
620      {Py_mod_exec, _random_exec},
621      {0, NULL}
622  };
623  
624  static int
_random_traverse(PyObject * module,visitproc visit,void * arg)625  _random_traverse(PyObject *module, visitproc visit, void *arg)
626  {
627      Py_VISIT(get_random_state(module)->Random_Type);
628      return 0;
629  }
630  
631  static int
_random_clear(PyObject * module)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  
639  static void
_random_free(void * module)640  _random_free(void *module)
641  {
642      _random_clear((PyObject *)module);
643  }
644  
645  static 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  
657  PyMODINIT_FUNC
PyInit__random(void)658  PyInit__random(void)
659  {
660      return PyModuleDef_Init(&_randommodule);
661  }
662