1/**********************************************************************
2
3  random.c -
4
5  $Author: nagachika $
6  created at: Fri Dec 24 16:39:21 JST 1993
7
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10**********************************************************************/
11
12/*
13This is based on trimmed version of MT19937.  To get the original version,
14contact <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>.
15
16The original copyright notice follows.
17
18   A C-program for MT19937, with initialization improved 2002/2/10.
19   Coded by Takuji Nishimura and Makoto Matsumoto.
20   This is a faster version by taking Shawn Cokus's optimization,
21   Matthe Bellew's simplification, Isaku Wada's real version.
22
23   Before using, initialize the state by using init_genrand(mt, seed)
24   or init_by_array(mt, init_key, key_length).
25
26   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
27   All rights reserved.
28
29   Redistribution and use in source and binary forms, with or without
30   modification, are permitted provided that the following conditions
31   are met:
32
33     1. Redistributions of source code must retain the above copyright
34        notice, this list of conditions and the following disclaimer.
35
36     2. Redistributions in binary form must reproduce the above copyright
37        notice, this list of conditions and the following disclaimer in the
38        documentation and/or other materials provided with the distribution.
39
40     3. The names of its contributors may not be used to endorse or promote
41        products derived from this software without specific prior written
42        permission.
43
44   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
47   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
48   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
49   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
50   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
51   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
52   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
53   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
54   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55
56
57   Any feedback is very welcome.
58   http://www.math.keio.ac.jp/matumoto/emt.html
59   email: matumoto@math.keio.ac.jp
60*/
61
62#include "ruby/ruby.h"
63
64#include <limits.h>
65#ifdef HAVE_UNISTD_H
66#include <unistd.h>
67#endif
68#include <time.h>
69#include <sys/types.h>
70#include <sys/stat.h>
71#ifdef HAVE_FCNTL_H
72#include <fcntl.h>
73#endif
74#include <math.h>
75#include <errno.h>
76#if defined(HAVE_SYS_TIME_H)
77#include <sys/time.h>
78#endif
79
80#ifdef _WIN32
81# if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0400
82#  undef _WIN32_WINNT
83#  define _WIN32_WINNT 0x400
84#  undef __WINCRYPT_H__
85# endif
86#include <wincrypt.h>
87#endif
88
89typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
90
91/* Period parameters */
92#define N 624
93#define M 397
94#define MATRIX_A 0x9908b0dfU	/* constant vector a */
95#define UMASK 0x80000000U	/* most significant w-r bits */
96#define LMASK 0x7fffffffU	/* least significant r bits */
97#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
98#define TWIST(u,v) ((MIXBITS((u),(v)) >> 1) ^ ((v)&1U ? MATRIX_A : 0U))
99
100enum {MT_MAX_STATE = N};
101
102struct MT {
103    /* assume int is enough to store 32bits */
104    unsigned int state[N]; /* the array for the state vector  */
105    unsigned int *next;
106    int left;
107};
108
109#define genrand_initialized(mt) ((mt)->next != 0)
110#define uninit_genrand(mt) ((mt)->next = 0)
111
112/* initializes state[N] with a seed */
113static void
114init_genrand(struct MT *mt, unsigned int s)
115{
116    int j;
117    mt->state[0] = s & 0xffffffffU;
118    for (j=1; j<N; j++) {
119        mt->state[j] = (1812433253U * (mt->state[j-1] ^ (mt->state[j-1] >> 30)) + j);
120        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
121        /* In the previous versions, MSBs of the seed affect   */
122        /* only MSBs of the array state[].                     */
123        /* 2002/01/09 modified by Makoto Matsumoto             */
124        mt->state[j] &= 0xffffffff;  /* for >32 bit machines */
125    }
126    mt->left = 1;
127    mt->next = mt->state + N;
128}
129
130/* initialize by an array with array-length */
131/* init_key is the array for initializing keys */
132/* key_length is its length */
133/* slight change for C++, 2004/2/26 */
134static void
135init_by_array(struct MT *mt, unsigned int init_key[], int key_length)
136{
137    int i, j, k;
138    init_genrand(mt, 19650218U);
139    i=1; j=0;
140    k = (N>key_length ? N : key_length);
141    for (; k; k--) {
142        mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1664525U))
143          + init_key[j] + j; /* non linear */
144        mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
145        i++; j++;
146        if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
147        if (j>=key_length) j=0;
148    }
149    for (k=N-1; k; k--) {
150        mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1566083941U))
151          - i; /* non linear */
152        mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
153        i++;
154        if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
155    }
156
157    mt->state[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
158}
159
160static void
161next_state(struct MT *mt)
162{
163    unsigned int *p = mt->state;
164    int j;
165
166    mt->left = N;
167    mt->next = mt->state;
168
169    for (j=N-M+1; --j; p++)
170        *p = p[M] ^ TWIST(p[0], p[1]);
171
172    for (j=M; --j; p++)
173        *p = p[M-N] ^ TWIST(p[0], p[1]);
174
175    *p = p[M-N] ^ TWIST(p[0], mt->state[0]);
176}
177
178/* generates a random number on [0,0xffffffff]-interval */
179static unsigned int
180genrand_int32(struct MT *mt)
181{
182    /* mt must be initialized */
183    unsigned int y;
184
185    if (--mt->left <= 0) next_state(mt);
186    y = *mt->next++;
187
188    /* Tempering */
189    y ^= (y >> 11);
190    y ^= (y << 7) & 0x9d2c5680;
191    y ^= (y << 15) & 0xefc60000;
192    y ^= (y >> 18);
193
194    return y;
195}
196
197/* generates a random number on [0,1) with 53-bit resolution*/
198static double
199genrand_real(struct MT *mt)
200{
201    /* mt must be initialized */
202    unsigned int a = genrand_int32(mt)>>5, b = genrand_int32(mt)>>6;
203    return(a*67108864.0+b)*(1.0/9007199254740992.0);
204}
205
206/* generates a random number on [0,1] with 53-bit resolution*/
207static double int_pair_to_real_inclusive(unsigned int a, unsigned int b);
208static double
209genrand_real2(struct MT *mt)
210{
211    /* mt must be initialized */
212    unsigned int a = genrand_int32(mt), b = genrand_int32(mt);
213    return int_pair_to_real_inclusive(a, b);
214}
215
216/* These real versions are due to Isaku Wada, 2002/01/09 added */
217
218#undef N
219#undef M
220
221typedef struct {
222    VALUE seed;
223    struct MT mt;
224} rb_random_t;
225
226#define DEFAULT_SEED_CNT 4
227
228static rb_random_t default_rand;
229
230static VALUE rand_init(struct MT *mt, VALUE vseed);
231static VALUE random_seed(void);
232
233static rb_random_t *
234rand_start(rb_random_t *r)
235{
236    struct MT *mt = &r->mt;
237    if (!genrand_initialized(mt)) {
238	r->seed = rand_init(mt, random_seed());
239    }
240    return r;
241}
242
243static struct MT *
244default_mt(void)
245{
246    return &rand_start(&default_rand)->mt;
247}
248
249unsigned int
250rb_genrand_int32(void)
251{
252    struct MT *mt = default_mt();
253    return genrand_int32(mt);
254}
255
256double
257rb_genrand_real(void)
258{
259    struct MT *mt = default_mt();
260    return genrand_real(mt);
261}
262
263#define BDIGITS(x) (RBIGNUM_DIGITS(x))
264#define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
265#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
266#define DIGSPERINT (SIZEOF_INT/SIZEOF_BDIGITS)
267#define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG)
268#define BIGDN(x) RSHIFT((x),BITSPERDIG)
269#define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1)))
270#define BDIGMAX ((BDIGIT)-1)
271
272#define roomof(n, m) (int)(((n)+(m)-1) / (m))
273#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
274#define SIZEOF_INT32 (31/CHAR_BIT + 1)
275
276static double
277int_pair_to_real_inclusive(unsigned int a, unsigned int b)
278{
279    VALUE x = rb_big_new(roomof(64, BITSPERDIG), 1);
280    VALUE m = rb_big_new(roomof(53, BITSPERDIG), 1);
281    BDIGIT *xd = BDIGITS(x);
282    int i = 0;
283    double r;
284
285    xd[i++] = (BDIGIT)b;
286#if BITSPERDIG < 32
287    xd[i++] = (BDIGIT)(b >> BITSPERDIG);
288#endif
289    xd[i++] = (BDIGIT)a;
290#if BITSPERDIG < 32
291    xd[i++] = (BDIGIT)(a >> BITSPERDIG);
292#endif
293    xd = BDIGITS(m);
294#if BITSPERDIG < 53
295    MEMZERO(xd, BDIGIT, roomof(53, BITSPERDIG) - 1);
296#endif
297    xd[53 / BITSPERDIG] = 1 << 53 % BITSPERDIG;
298    xd[0] |= 1;
299    x = rb_big_mul(x, m);
300    if (FIXNUM_P(x)) {
301#if CHAR_BIT * SIZEOF_LONG > 64
302	r = (double)(FIX2ULONG(x) >> 64);
303#else
304	return 0.0;
305#endif
306    }
307    else {
308#if 64 % BITSPERDIG == 0
309	long len = RBIGNUM_LEN(x);
310	xd = BDIGITS(x);
311	MEMMOVE(xd, xd + 64 / BITSPERDIG, BDIGIT, len - 64 / BITSPERDIG);
312	MEMZERO(xd + len - 64 / BITSPERDIG, BDIGIT, 64 / BITSPERDIG);
313	r = rb_big2dbl(x);
314#else
315	x = rb_big_rshift(x, INT2FIX(64));
316	if (FIXNUM_P(x)) {
317	    r = (double)FIX2ULONG(x);
318	}
319	else {
320	    r = rb_big2dbl(x);
321	}
322#endif
323    }
324    return ldexp(r, -53);
325}
326
327VALUE rb_cRandom;
328#define id_minus '-'
329#define id_plus  '+'
330static ID id_rand, id_bytes;
331
332/* :nodoc: */
333static void
334random_mark(void *ptr)
335{
336    rb_gc_mark(((rb_random_t *)ptr)->seed);
337}
338
339static void
340random_free(void *ptr)
341{
342    if (ptr != &default_rand)
343	xfree(ptr);
344}
345
346static size_t
347random_memsize(const void *ptr)
348{
349    return ptr ? sizeof(rb_random_t) : 0;
350}
351
352static const rb_data_type_t random_data_type = {
353    "random",
354    {
355	random_mark,
356	random_free,
357	random_memsize,
358    },
359};
360
361static rb_random_t *
362get_rnd(VALUE obj)
363{
364    rb_random_t *ptr;
365    TypedData_Get_Struct(obj, rb_random_t, &random_data_type, ptr);
366    return ptr;
367}
368
369static rb_random_t *
370try_get_rnd(VALUE obj)
371{
372    if (obj == rb_cRandom) {
373	return rand_start(&default_rand);
374    }
375    if (!rb_typeddata_is_kind_of(obj, &random_data_type)) return NULL;
376    return DATA_PTR(obj);
377}
378
379/* :nodoc: */
380static VALUE
381random_alloc(VALUE klass)
382{
383    rb_random_t *rnd;
384    VALUE obj = TypedData_Make_Struct(klass, rb_random_t, &random_data_type, rnd);
385    rnd->seed = INT2FIX(0);
386    return obj;
387}
388
389static VALUE
390rand_init(struct MT *mt, VALUE vseed)
391{
392    volatile VALUE seed;
393    long blen = 0;
394    long fixnum_seed;
395    int i, j, len;
396    unsigned int buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0;
397
398    seed = rb_to_int(vseed);
399    switch (TYPE(seed)) {
400      case T_FIXNUM:
401	len = 1;
402	fixnum_seed = FIX2LONG(seed);
403        if (fixnum_seed < 0)
404            fixnum_seed = -fixnum_seed;
405	buf[0] = (unsigned int)(fixnum_seed & 0xffffffff);
406#if SIZEOF_LONG > SIZEOF_INT32
407	if ((long)(int32_t)fixnum_seed != fixnum_seed) {
408	    if ((buf[1] = (unsigned int)(fixnum_seed >> 32)) != 0) ++len;
409	}
410#endif
411	break;
412      case T_BIGNUM:
413	blen = RBIGNUM_LEN(seed);
414	if (blen == 0) {
415	    len = 1;
416	}
417	else {
418	    if (blen > MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS)
419		blen = MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS;
420	    len = roomof((int)blen * SIZEOF_BDIGITS, SIZEOF_INT32);
421	}
422	/* allocate ints for init_by_array */
423	if (len > numberof(buf0)) buf = ALLOC_N(unsigned int, len);
424	memset(buf, 0, len * sizeof(*buf));
425	len = 0;
426	for (i = (int)(blen-1); 0 <= i; i--) {
427	    j = i * SIZEOF_BDIGITS / SIZEOF_INT32;
428#if SIZEOF_BDIGITS < SIZEOF_INT32
429	    buf[j] <<= BITSPERDIG;
430#endif
431	    buf[j] |= RBIGNUM_DIGITS(seed)[i];
432	    if (!len && buf[j]) len = j;
433	}
434	++len;
435	break;
436      default:
437	rb_raise(rb_eTypeError, "failed to convert %s into Integer",
438		 rb_obj_classname(vseed));
439    }
440    if (len <= 1) {
441        init_genrand(mt, buf[0]);
442    }
443    else {
444        if (buf[len-1] == 1) /* remove leading-zero-guard */
445            len--;
446        init_by_array(mt, buf, len);
447    }
448    if (buf != buf0) xfree(buf);
449    return seed;
450}
451
452/*
453 * call-seq:
454 *   Random.new(seed = Random.new_seed) -> prng
455 *
456 * Creates a new PRNG using +seed+ to set the initial state. If +seed+ is
457 * omitted, the generator is initialized with Random.new_seed.
458 *
459 * See Random.srand for more information on the use of seed values.
460 */
461static VALUE
462random_init(int argc, VALUE *argv, VALUE obj)
463{
464    VALUE vseed;
465    rb_random_t *rnd = get_rnd(obj);
466
467    if (argc == 0) {
468	rb_check_frozen(obj);
469	vseed = random_seed();
470    }
471    else {
472	rb_scan_args(argc, argv, "01", &vseed);
473	rb_check_copyable(obj, vseed);
474    }
475    rnd->seed = rand_init(&rnd->mt, vseed);
476    return obj;
477}
478
479#define DEFAULT_SEED_LEN (DEFAULT_SEED_CNT * (int)sizeof(int))
480
481#if defined(S_ISCHR) && !defined(DOSISH)
482# define USE_DEV_URANDOM 1
483#else
484# define USE_DEV_URANDOM 0
485#endif
486
487static void
488fill_random_seed(unsigned int seed[DEFAULT_SEED_CNT])
489{
490    static int n = 0;
491    struct timeval tv;
492#if USE_DEV_URANDOM
493    int fd;
494    struct stat statbuf;
495#elif defined(_WIN32)
496    HCRYPTPROV prov;
497#endif
498
499    memset(seed, 0, DEFAULT_SEED_LEN);
500
501#if USE_DEV_URANDOM
502    if ((fd = rb_cloexec_open("/dev/urandom", O_RDONLY
503#ifdef O_NONBLOCK
504            |O_NONBLOCK
505#endif
506#ifdef O_NOCTTY
507            |O_NOCTTY
508#endif
509            , 0)) >= 0) {
510        rb_update_max_fd(fd);
511        if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
512	    if (read(fd, seed, DEFAULT_SEED_LEN) < DEFAULT_SEED_LEN) {
513		/* abandon */;
514	    }
515        }
516        close(fd);
517    }
518#elif defined(_WIN32)
519    if (CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
520	CryptGenRandom(prov, DEFAULT_SEED_LEN, (void *)seed);
521	CryptReleaseContext(prov, 0);
522    }
523#endif
524
525    gettimeofday(&tv, 0);
526    seed[0] ^= tv.tv_usec;
527    seed[1] ^= (unsigned int)tv.tv_sec;
528#if SIZEOF_TIME_T > SIZEOF_INT
529    seed[0] ^= (unsigned int)((time_t)tv.tv_sec >> SIZEOF_INT * CHAR_BIT);
530#endif
531    seed[2] ^= getpid() ^ (n++ << 16);
532    seed[3] ^= (unsigned int)(VALUE)&seed;
533#if SIZEOF_VOIDP > SIZEOF_INT
534    seed[2] ^= (unsigned int)((VALUE)&seed >> SIZEOF_INT * CHAR_BIT);
535#endif
536}
537
538static VALUE
539make_seed_value(const void *ptr)
540{
541    const long len = DEFAULT_SEED_LEN/SIZEOF_BDIGITS;
542    BDIGIT *digits;
543    NEWOBJ_OF(big, struct RBignum, rb_cBignum, T_BIGNUM);
544
545    RBIGNUM_SET_SIGN(big, 1);
546    rb_big_resize((VALUE)big, len + 1);
547    digits = RBIGNUM_DIGITS(big);
548
549    MEMCPY(digits, ptr, char, DEFAULT_SEED_LEN);
550
551    /* set leading-zero-guard if need. */
552    digits[len] =
553#if SIZEOF_INT32 / SIZEOF_BDIGITS > 1
554	digits[len-2] <= 1 && digits[len-1] == 0
555#else
556	digits[len-1] <= 1
557#endif
558	? 1 : 0;
559
560    return rb_big_norm((VALUE)big);
561}
562
563/*
564 * call-seq: Random.new_seed -> integer
565 *
566 * Returns an arbitrary seed value. This is used by Random.new
567 * when no seed value is specified as an argument.
568 *
569 *   Random.new_seed  #=> 115032730400174366788466674494640623225
570 */
571static VALUE
572random_seed(void)
573{
574    unsigned int buf[DEFAULT_SEED_CNT];
575    fill_random_seed(buf);
576    return make_seed_value(buf);
577}
578
579/*
580 * call-seq: prng.seed -> integer
581 *
582 * Returns the seed value used to initialize the generator. This may be used to
583 * initialize another generator with the same state at a later time, causing it
584 * to produce the same sequence of numbers.
585 *
586 *   prng1 = Random.new(1234)
587 *   prng1.seed       #=> 1234
588 *   prng1.rand(100)  #=> 47
589 *
590 *   prng2 = Random.new(prng1.seed)
591 *   prng2.rand(100)  #=> 47
592 */
593static VALUE
594random_get_seed(VALUE obj)
595{
596    return get_rnd(obj)->seed;
597}
598
599/* :nodoc: */
600static VALUE
601random_copy(VALUE obj, VALUE orig)
602{
603    rb_random_t *rnd1, *rnd2;
604    struct MT *mt;
605
606    if (!OBJ_INIT_COPY(obj, orig)) return obj;
607
608    rnd1 = get_rnd(obj);
609    rnd2 = get_rnd(orig);
610    mt = &rnd1->mt;
611
612    *rnd1 = *rnd2;
613    mt->next = mt->state + numberof(mt->state) - mt->left + 1;
614    return obj;
615}
616
617static VALUE
618mt_state(const struct MT *mt)
619{
620    VALUE bigo = rb_big_new(sizeof(mt->state) / sizeof(BDIGIT), 1);
621    BDIGIT *d = RBIGNUM_DIGITS(bigo);
622    int i;
623
624    for (i = 0; i < numberof(mt->state); ++i) {
625	unsigned int x = mt->state[i];
626#if SIZEOF_BDIGITS < SIZEOF_INT32
627	int j;
628	for (j = 0; j < SIZEOF_INT32 / SIZEOF_BDIGITS; ++j) {
629	    *d++ = BIGLO(x);
630	    x = BIGDN(x);
631	}
632#else
633	*d++ = (BDIGIT)x;
634#endif
635    }
636    return rb_big_norm(bigo);
637}
638
639/* :nodoc: */
640static VALUE
641random_state(VALUE obj)
642{
643    rb_random_t *rnd = get_rnd(obj);
644    return mt_state(&rnd->mt);
645}
646
647/* :nodoc: */
648static VALUE
649random_s_state(VALUE klass)
650{
651    return mt_state(&default_rand.mt);
652}
653
654/* :nodoc: */
655static VALUE
656random_left(VALUE obj)
657{
658    rb_random_t *rnd = get_rnd(obj);
659    return INT2FIX(rnd->mt.left);
660}
661
662/* :nodoc: */
663static VALUE
664random_s_left(VALUE klass)
665{
666    return INT2FIX(default_rand.mt.left);
667}
668
669/* :nodoc: */
670static VALUE
671random_dump(VALUE obj)
672{
673    rb_random_t *rnd = get_rnd(obj);
674    VALUE dump = rb_ary_new2(3);
675
676    rb_ary_push(dump, mt_state(&rnd->mt));
677    rb_ary_push(dump, INT2FIX(rnd->mt.left));
678    rb_ary_push(dump, rnd->seed);
679
680    return dump;
681}
682
683/* :nodoc: */
684static VALUE
685random_load(VALUE obj, VALUE dump)
686{
687    rb_random_t *rnd = get_rnd(obj);
688    struct MT *mt = &rnd->mt;
689    VALUE state, left = INT2FIX(1), seed = INT2FIX(0);
690    VALUE *ary;
691    unsigned long x;
692
693    rb_check_copyable(obj, dump);
694    Check_Type(dump, T_ARRAY);
695    ary = RARRAY_PTR(dump);
696    switch (RARRAY_LEN(dump)) {
697      case 3:
698	seed = ary[2];
699      case 2:
700	left = ary[1];
701      case 1:
702	state = ary[0];
703	break;
704      default:
705	rb_raise(rb_eArgError, "wrong dump data");
706    }
707    memset(mt->state, 0, sizeof(mt->state));
708    if (FIXNUM_P(state)) {
709	x = FIX2ULONG(state);
710	mt->state[0] = (unsigned int)x;
711#if SIZEOF_LONG / SIZEOF_INT >= 2
712	mt->state[1] = (unsigned int)(x >> BITSPERDIG);
713#endif
714#if SIZEOF_LONG / SIZEOF_INT >= 3
715	mt->state[2] = (unsigned int)(x >> 2 * BITSPERDIG);
716#endif
717#if SIZEOF_LONG / SIZEOF_INT >= 4
718	mt->state[3] = (unsigned int)(x >> 3 * BITSPERDIG);
719#endif
720    }
721    else {
722	BDIGIT *d;
723	long len;
724	Check_Type(state, T_BIGNUM);
725	len = RBIGNUM_LEN(state);
726	if (len > roomof(sizeof(mt->state), SIZEOF_BDIGITS)) {
727	    len = roomof(sizeof(mt->state), SIZEOF_BDIGITS);
728	}
729#if SIZEOF_BDIGITS < SIZEOF_INT
730	else if (len % DIGSPERINT) {
731	    d = RBIGNUM_DIGITS(state) + len;
732# if DIGSPERINT == 2
733	    --len;
734	    x = *--d;
735# else
736	    x = 0;
737	    do {
738		x = (x << BITSPERDIG) | *--d;
739	    } while (--len % DIGSPERINT);
740# endif
741	    mt->state[len / DIGSPERINT] = (unsigned int)x;
742	}
743#endif
744	if (len > 0) {
745	    d = BDIGITS(state) + len;
746	    do {
747		--len;
748		x = *--d;
749# if DIGSPERINT == 2
750		--len;
751		x = (x << BITSPERDIG) | *--d;
752# elif SIZEOF_BDIGITS < SIZEOF_INT
753		do {
754		    x = (x << BITSPERDIG) | *--d;
755		} while (--len % DIGSPERINT);
756# endif
757		mt->state[len / DIGSPERINT] = (unsigned int)x;
758	    } while (len > 0);
759	}
760    }
761    x = NUM2ULONG(left);
762    if (x > numberof(mt->state)) {
763	rb_raise(rb_eArgError, "wrong value");
764    }
765    mt->left = (unsigned int)x;
766    mt->next = mt->state + numberof(mt->state) - x + 1;
767    rnd->seed = rb_to_int(seed);
768
769    return obj;
770}
771
772/*
773 * call-seq:
774 *   srand(number = Random.new_seed) -> old_seed
775 *
776 * Seeds the system pseudo-random number generator, Random::DEFAULT, with
777 * +number+.  The previous seed value is returned.
778 *
779 * If +number+ is omitted, seeds the generator using a source of entropy
780 * provided by the operating system, if available (/dev/urandom on Unix systems
781 * or the RSA cryptographic provider on Windows), which is then combined with
782 * the time, the process id, and a sequence number.
783 *
784 * srand may be used to ensure repeatable sequences of pseudo-random numbers
785 * between different runs of the program. By setting the seed to a known value,
786 * programs can be made deterministic during testing.
787 *
788 *   srand 1234               # => 268519324636777531569100071560086917274
789 *   [ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
790 *   [ rand(10), rand(1000) ] # => [4, 664]
791 *   srand 1234               # => 1234
792 *   [ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
793 */
794
795static VALUE
796rb_f_srand(int argc, VALUE *argv, VALUE obj)
797{
798    VALUE seed, old;
799    rb_random_t *r = &default_rand;
800
801    rb_secure(4);
802    if (argc == 0) {
803	seed = random_seed();
804    }
805    else {
806	rb_scan_args(argc, argv, "01", &seed);
807    }
808    old = r->seed;
809    r->seed = rand_init(&r->mt, seed);
810
811    return old;
812}
813
814static unsigned long
815make_mask(unsigned long x)
816{
817    x = x | x >> 1;
818    x = x | x >> 2;
819    x = x | x >> 4;
820    x = x | x >> 8;
821    x = x | x >> 16;
822#if 4 < SIZEOF_LONG
823    x = x | x >> 32;
824#endif
825    return x;
826}
827
828static unsigned long
829limited_rand(struct MT *mt, unsigned long limit)
830{
831    /* mt must be initialized */
832    int i;
833    unsigned long val, mask;
834
835    if (!limit) return 0;
836    mask = make_mask(limit);
837  retry:
838    val = 0;
839    for (i = SIZEOF_LONG/SIZEOF_INT32-1; 0 <= i; i--) {
840        if ((mask >> (i * 32)) & 0xffffffff) {
841            val |= (unsigned long)genrand_int32(mt) << (i * 32);
842            val &= mask;
843            if (limit < val)
844                goto retry;
845        }
846    }
847    return val;
848}
849
850static VALUE
851limited_big_rand(struct MT *mt, struct RBignum *limit)
852{
853    /* mt must be initialized */
854    unsigned long mask, lim, rnd;
855    struct RBignum *val;
856    long i, len;
857    int boundary;
858
859    len = (RBIGNUM_LEN(limit) * SIZEOF_BDIGITS + 3) / 4;
860    val = (struct RBignum *)rb_big_clone((VALUE)limit);
861    RBIGNUM_SET_SIGN(val, 1);
862#if SIZEOF_BDIGITS == 2
863# define BIG_GET32(big,i) \
864    (RBIGNUM_DIGITS(big)[(i)*2] | \
865     ((i)*2+1 < RBIGNUM_LEN(big) ? \
866      (RBIGNUM_DIGITS(big)[(i)*2+1] << 16) : \
867      0))
868# define BIG_SET32(big,i,d) \
869    ((RBIGNUM_DIGITS(big)[(i)*2] = (d) & 0xffff), \
870     ((i)*2+1 < RBIGNUM_LEN(big) ? \
871      (RBIGNUM_DIGITS(big)[(i)*2+1] = (d) >> 16) : \
872      0))
873#else
874    /* SIZEOF_BDIGITS == 4 */
875# define BIG_GET32(big,i) (RBIGNUM_DIGITS(big)[(i)])
876# define BIG_SET32(big,i,d) (RBIGNUM_DIGITS(big)[(i)] = (d))
877#endif
878  retry:
879    mask = 0;
880    boundary = 1;
881    for (i = len-1; 0 <= i; i--) {
882        lim = BIG_GET32(limit, i);
883        mask = mask ? 0xffffffff : make_mask(lim);
884        if (mask) {
885            rnd = genrand_int32(mt) & mask;
886            if (boundary) {
887                if (lim < rnd)
888                    goto retry;
889                if (rnd < lim)
890                    boundary = 0;
891            }
892        }
893        else {
894            rnd = 0;
895        }
896        BIG_SET32(val, i, (BDIGIT)rnd);
897    }
898    return rb_big_norm((VALUE)val);
899}
900
901/*
902 * Returns random unsigned long value in [0, +limit+].
903 *
904 * Note that +limit+ is included, and the range of the argument and the
905 * return value depends on environments.
906 */
907unsigned long
908rb_genrand_ulong_limited(unsigned long limit)
909{
910    return limited_rand(default_mt(), limit);
911}
912
913unsigned int
914rb_random_int32(VALUE obj)
915{
916    rb_random_t *rnd = try_get_rnd(obj);
917    if (!rnd) {
918#if SIZEOF_LONG * CHAR_BIT > 32
919	VALUE lim = ULONG2NUM(0x100000000UL);
920#elif defined HAVE_LONG_LONG
921	VALUE lim = ULL2NUM((LONG_LONG)0xffffffff+1);
922#else
923	VALUE lim = rb_big_plus(ULONG2NUM(0xffffffff), INT2FIX(1));
924#endif
925	return (unsigned int)NUM2ULONG(rb_funcall2(obj, id_rand, 1, &lim));
926    }
927    return genrand_int32(&rnd->mt);
928}
929
930double
931rb_random_real(VALUE obj)
932{
933    rb_random_t *rnd = try_get_rnd(obj);
934    if (!rnd) {
935	VALUE v = rb_funcall2(obj, id_rand, 0, 0);
936	double d = NUM2DBL(v);
937	if (d < 0.0) {
938	    rb_raise(rb_eRangeError, "random number too small %g", d);
939	}
940	else if (d >= 1.0) {
941	    rb_raise(rb_eRangeError, "random number too big %g", d);
942	}
943	return d;
944    }
945    return genrand_real(&rnd->mt);
946}
947
948static inline VALUE
949ulong_to_num_plus_1(unsigned long n)
950{
951#if HAVE_LONG_LONG
952    return ULL2NUM((LONG_LONG)n+1);
953#else
954    if (n >= ULONG_MAX) {
955	return rb_big_plus(ULONG2NUM(n), INT2FIX(1));
956    }
957    return ULONG2NUM(n+1);
958#endif
959}
960
961unsigned long
962rb_random_ulong_limited(VALUE obj, unsigned long limit)
963{
964    rb_random_t *rnd = try_get_rnd(obj);
965    if (!rnd) {
966	extern int rb_num_negative_p(VALUE);
967	VALUE lim = ulong_to_num_plus_1(limit);
968	VALUE v = rb_to_int(rb_funcall2(obj, id_rand, 1, &lim));
969	unsigned long r = NUM2ULONG(v);
970	if (rb_num_negative_p(v)) {
971	    rb_raise(rb_eRangeError, "random number too small %ld", r);
972	}
973	if (r > limit) {
974	    rb_raise(rb_eRangeError, "random number too big %ld", r);
975	}
976	return r;
977    }
978    return limited_rand(&rnd->mt, limit);
979}
980
981/*
982 * call-seq: prng.bytes(size) -> a_string
983 *
984 * Returns a random binary string containing +size+ bytes.
985 *
986 *   random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO"
987 *   random_string.size                   # => 10
988 */
989static VALUE
990random_bytes(VALUE obj, VALUE len)
991{
992    return rb_random_bytes(obj, NUM2LONG(rb_to_int(len)));
993}
994
995VALUE
996rb_random_bytes(VALUE obj, long n)
997{
998    rb_random_t *rnd = try_get_rnd(obj);
999    VALUE bytes;
1000    char *ptr;
1001    unsigned int r, i;
1002
1003    if (!rnd) {
1004	VALUE len = LONG2NUM(n);
1005	return rb_funcall2(obj, id_bytes, 1, &len);
1006    }
1007    bytes = rb_str_new(0, n);
1008    ptr = RSTRING_PTR(bytes);
1009    for (; n >= SIZEOF_INT32; n -= SIZEOF_INT32) {
1010	r = genrand_int32(&rnd->mt);
1011	i = SIZEOF_INT32;
1012	do {
1013	    *ptr++ = (char)r;
1014	    r >>= CHAR_BIT;
1015        } while (--i);
1016    }
1017    if (n > 0) {
1018	r = genrand_int32(&rnd->mt);
1019	do {
1020	    *ptr++ = (char)r;
1021	    r >>= CHAR_BIT;
1022	} while (--n);
1023    }
1024    return bytes;
1025}
1026
1027static VALUE
1028range_values(VALUE vmax, VALUE *begp, VALUE *endp, int *exclp)
1029{
1030    VALUE end, r;
1031
1032    if (!rb_range_values(vmax, begp, &end, exclp)) return Qfalse;
1033    if (endp) *endp = end;
1034    if (!rb_respond_to(end, id_minus)) return Qfalse;
1035    r = rb_funcall2(end, id_minus, 1, begp);
1036    if (NIL_P(r)) return Qfalse;
1037    return r;
1038}
1039
1040static VALUE
1041rand_int(struct MT *mt, VALUE vmax, int restrictive)
1042{
1043    /* mt must be initialized */
1044    long max;
1045    unsigned long r;
1046
1047    if (FIXNUM_P(vmax)) {
1048	max = FIX2LONG(vmax);
1049	if (!max) return Qnil;
1050	if (max < 0) {
1051	    if (restrictive) return Qnil;
1052	    max = -max;
1053	}
1054	r = limited_rand(mt, (unsigned long)max - 1);
1055	return ULONG2NUM(r);
1056    }
1057    else {
1058	VALUE ret;
1059	if (rb_bigzero_p(vmax)) return Qnil;
1060	if (!RBIGNUM_SIGN(vmax)) {
1061	    if (restrictive) return Qnil;
1062	    vmax = rb_big_clone(vmax);
1063	    RBIGNUM_SET_SIGN(vmax, 1);
1064	}
1065	vmax = rb_big_minus(vmax, INT2FIX(1));
1066	if (FIXNUM_P(vmax)) {
1067	    max = FIX2LONG(vmax);
1068	    if (max == -1) return Qnil;
1069	    r = limited_rand(mt, max);
1070	    return LONG2NUM(r);
1071	}
1072	ret = limited_big_rand(mt, RBIGNUM(vmax));
1073	RB_GC_GUARD(vmax);
1074	return ret;
1075    }
1076}
1077
1078static inline double
1079float_value(VALUE v)
1080{
1081    double x = RFLOAT_VALUE(v);
1082    if (isinf(x) || isnan(x)) {
1083	VALUE error = INT2FIX(EDOM);
1084	rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
1085    }
1086    return x;
1087}
1088
1089static inline VALUE
1090rand_range(struct MT* mt, VALUE range)
1091{
1092    VALUE beg = Qundef, end = Qundef, vmax, v;
1093    int excl = 0;
1094
1095    if ((v = vmax = range_values(range, &beg, &end, &excl)) == Qfalse)
1096	return Qfalse;
1097    if (!RB_TYPE_P(vmax, T_FLOAT) && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
1098	long max;
1099	vmax = v;
1100	v = Qnil;
1101	if (FIXNUM_P(vmax)) {
1102	  fixnum:
1103	    if ((max = FIX2LONG(vmax) - excl) >= 0) {
1104		unsigned long r = limited_rand(mt, (unsigned long)max);
1105		v = ULONG2NUM(r);
1106	    }
1107	}
1108	else if (BUILTIN_TYPE(vmax) == T_BIGNUM && RBIGNUM_SIGN(vmax) && !rb_bigzero_p(vmax)) {
1109	    vmax = excl ? rb_big_minus(vmax, INT2FIX(1)) : rb_big_norm(vmax);
1110	    if (FIXNUM_P(vmax)) {
1111		excl = 0;
1112		goto fixnum;
1113	    }
1114	    v = limited_big_rand(mt, RBIGNUM(vmax));
1115	}
1116    }
1117    else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
1118	int scale = 1;
1119	double max = RFLOAT_VALUE(v), mid = 0.5, r;
1120	if (isinf(max)) {
1121	    double min = float_value(rb_to_float(beg)) / 2.0;
1122	    max = float_value(rb_to_float(end)) / 2.0;
1123	    scale = 2;
1124	    mid = max + min;
1125	    max -= min;
1126	}
1127	else {
1128	    float_value(v);
1129	}
1130	v = Qnil;
1131	if (max > 0.0) {
1132	    if (excl) {
1133		r = genrand_real(mt);
1134	    }
1135	    else {
1136		r = genrand_real2(mt);
1137	    }
1138	    if (scale > 1) {
1139		return rb_float_new(+(+(+(r - 0.5) * max) * scale) + mid);
1140	    }
1141	    v = rb_float_new(r * max);
1142	}
1143	else if (max == 0.0 && !excl) {
1144	    v = rb_float_new(0.0);
1145	}
1146    }
1147
1148    if (FIXNUM_P(beg) && FIXNUM_P(v)) {
1149	long x = FIX2LONG(beg) + FIX2LONG(v);
1150	return LONG2NUM(x);
1151    }
1152    switch (TYPE(v)) {
1153      case T_NIL:
1154	break;
1155      case T_BIGNUM:
1156	return rb_big_plus(v, beg);
1157      case T_FLOAT: {
1158	VALUE f = rb_check_to_float(beg);
1159	if (!NIL_P(f)) {
1160	    return DBL2NUM(RFLOAT_VALUE(v) + RFLOAT_VALUE(f));
1161	}
1162      }
1163      default:
1164	return rb_funcall2(beg, id_plus, 1, &v);
1165    }
1166
1167    return v;
1168}
1169
1170static VALUE rand_random(int argc, VALUE *argv, rb_random_t *rnd);
1171
1172/*
1173 * call-seq:
1174 *   prng.rand -> float
1175 *   prng.rand(max) -> number
1176 *
1177 * When +max+ is an Integer, +rand+ returns a random integer greater than
1178 * or equal to zero and less than +max+. Unlike Kernel.rand, when +max+
1179 * is a negative integer or zero, +rand+ raises an ArgumentError.
1180 *
1181 *   prng = Random.new
1182 *   prng.rand(100)       # => 42
1183 *
1184 * When +max+ is a Float, +rand+ returns a random floating point number
1185 * between 0.0 and +max+, including 0.0 and excluding +max+.
1186 *
1187 *   prng.rand(1.5)       # => 1.4600282860034115
1188 *
1189 * When +max+ is a Range, +rand+ returns a random number where
1190 * range.member?(number) == true.
1191 *
1192 *   prng.rand(5..9)      # => one of [5, 6, 7, 8, 9]
1193 *   prng.rand(5...9)     # => one of [5, 6, 7, 8]
1194 *   prng.rand(5.0..9.0)  # => between 5.0 and 9.0, including 9.0
1195 *   prng.rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0
1196 *
1197 * Both the beginning and ending values of the range must respond to subtract
1198 * (<tt>-</tt>) and add (<tt>+</tt>)methods, or rand will raise an
1199 * ArgumentError.
1200 */
1201static VALUE
1202random_rand(int argc, VALUE *argv, VALUE obj)
1203{
1204    return rand_random(argc, argv, get_rnd(obj));
1205}
1206
1207static VALUE
1208rand_random(int argc, VALUE *argv, rb_random_t *rnd)
1209{
1210    VALUE vmax, v;
1211
1212    if (argc == 0) {
1213	return rb_float_new(genrand_real(&rnd->mt));
1214    }
1215    else {
1216	rb_check_arity(argc, 0, 1);
1217    }
1218    vmax = argv[0];
1219    if (NIL_P(vmax)) {
1220	v = Qnil;
1221    }
1222    else if (!RB_TYPE_P(vmax, T_FLOAT) && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
1223	v = rand_int(&rnd->mt, v, 1);
1224    }
1225    else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
1226	double max = float_value(v);
1227	if (max > 0.0)
1228	    v = rb_float_new(max * genrand_real(&rnd->mt));
1229	else
1230	    v = Qnil;
1231    }
1232    else if ((v = rand_range(&rnd->mt, vmax)) != Qfalse) {
1233	/* nothing to do */
1234    }
1235    else {
1236	v = Qnil;
1237	(void)NUM2LONG(vmax);
1238    }
1239    if (NIL_P(v)) {
1240	VALUE mesg = rb_str_new_cstr("invalid argument - ");
1241	rb_str_append(mesg, rb_obj_as_string(argv[0]));
1242	rb_exc_raise(rb_exc_new3(rb_eArgError, mesg));
1243    }
1244
1245    return v;
1246}
1247
1248/*
1249 * call-seq:
1250 *   prng1 == prng2 -> true or false
1251 *
1252 * Returns true if the two generators have the same internal state, otherwise
1253 * false.  Equivalent generators will return the same sequence of
1254 * pseudo-random numbers.  Two generators will generally have the same state
1255 * only if they were initialized with the same seed
1256 *
1257 *   Random.new == Random.new             # => false
1258 *   Random.new(1234) == Random.new(1234) # => true
1259 *
1260 * and have the same invocation history.
1261 *
1262 *   prng1 = Random.new(1234)
1263 *   prng2 = Random.new(1234)
1264 *   prng1 == prng2 # => true
1265 *
1266 *   prng1.rand     # => 0.1915194503788923
1267 *   prng1 == prng2 # => false
1268 *
1269 *   prng2.rand     # => 0.1915194503788923
1270 *   prng1 == prng2 # => true
1271 */
1272static VALUE
1273random_equal(VALUE self, VALUE other)
1274{
1275    rb_random_t *r1, *r2;
1276    if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse;
1277    r1 = get_rnd(self);
1278    r2 = get_rnd(other);
1279    if (!RTEST(rb_funcall2(r1->seed, rb_intern("=="), 1, &r2->seed))) return Qfalse;
1280    if (memcmp(r1->mt.state, r2->mt.state, sizeof(r1->mt.state))) return Qfalse;
1281    if ((r1->mt.next - r1->mt.state) != (r2->mt.next - r2->mt.state)) return Qfalse;
1282    if (r1->mt.left != r2->mt.left) return Qfalse;
1283    return Qtrue;
1284}
1285
1286/*
1287 * call-seq:
1288 *   rand(max=0)    -> number
1289 *
1290 * If called without an argument, or if <tt>max.to_i.abs == 0</tt>, rand
1291 * returns a pseudo-random floating point number between 0.0 and 1.0,
1292 * including 0.0 and excluding 1.0.
1293 *
1294 *   rand        #=> 0.2725926052826416
1295 *
1296 * When +max.abs+ is greater than or equal to 1, +rand+ returns a pseudo-random
1297 * integer greater than or equal to 0 and less than +max.to_i.abs+.
1298 *
1299 *   rand(100)   #=> 12
1300 *
1301 * When +max+ is a Range, +rand+ returns a random number where
1302 * range.member?(number) == true.
1303 *
1304 * Negative or floating point values for +max+ are allowed, but may give
1305 * surprising results.
1306 *
1307 *   rand(-100) # => 87
1308 *   rand(-0.5) # => 0.8130921818028143
1309 *   rand(1.9)  # equivalent to rand(1), which is always 0
1310 *
1311 * Kernel.srand may be used to ensure that sequences of random numbers are
1312 * reproducible between different runs of a program.
1313 *
1314 * See also Random.rand.
1315 */
1316
1317static VALUE
1318rb_f_rand(int argc, VALUE *argv, VALUE obj)
1319{
1320    VALUE v, vmax, r;
1321    struct MT *mt = default_mt();
1322
1323    if (argc == 0) goto zero_arg;
1324    rb_scan_args(argc, argv, "01", &vmax);
1325    if (NIL_P(vmax)) goto zero_arg;
1326    if ((v = rand_range(mt, vmax)) != Qfalse) {
1327	return v;
1328    }
1329    vmax = rb_to_int(vmax);
1330    if (vmax == INT2FIX(0) || NIL_P(r = rand_int(mt, vmax, 0))) {
1331      zero_arg:
1332	return DBL2NUM(genrand_real(mt));
1333    }
1334    return r;
1335}
1336
1337/*
1338 * call-seq:
1339 *   Random.rand -> float
1340 *   Random.rand(max) -> number
1341 *
1342 * Alias of Random::DEFAULT.rand.
1343 */
1344
1345static VALUE
1346random_s_rand(int argc, VALUE *argv, VALUE obj)
1347{
1348    return rand_random(argc, argv, rand_start(&default_rand));
1349}
1350
1351#define SIP_HASH_STREAMING 0
1352#define sip_hash24 ruby_sip_hash24
1353#if !defined _WIN32 && !defined BYTE_ORDER
1354# ifdef WORDS_BIGENDIAN
1355#   define BYTE_ORDER BIG_ENDIAN
1356# else
1357#   define BYTE_ORDER LITTLE_ENDIAN
1358# endif
1359# ifndef LITTLE_ENDIAN
1360#   define LITTLE_ENDIAN 1234
1361# endif
1362# ifndef BIG_ENDIAN
1363#   define BIG_ENDIAN    4321
1364# endif
1365#endif
1366#include "siphash.c"
1367
1368static st_index_t hashseed;
1369static union {
1370    uint8_t key[16];
1371    uint32_t u32[(16 * sizeof(uint8_t) - 1) / sizeof(uint32_t)];
1372} sipseed;
1373
1374static VALUE
1375init_randomseed(struct MT *mt, unsigned int initial[DEFAULT_SEED_CNT])
1376{
1377    VALUE seed;
1378    fill_random_seed(initial);
1379    init_by_array(mt, initial, DEFAULT_SEED_CNT);
1380    seed = make_seed_value(initial);
1381    memset(initial, 0, DEFAULT_SEED_LEN);
1382    return seed;
1383}
1384
1385void
1386Init_RandomSeed(void)
1387{
1388    rb_random_t *r = &default_rand;
1389    unsigned int initial[DEFAULT_SEED_CNT];
1390    struct MT *mt = &r->mt;
1391    VALUE seed = init_randomseed(mt, initial);
1392    int i;
1393
1394    hashseed = genrand_int32(mt);
1395#if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8
1396    hashseed <<= 32;
1397    hashseed |= genrand_int32(mt);
1398#endif
1399#if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8
1400    hashseed <<= 32;
1401    hashseed |= genrand_int32(mt);
1402#endif
1403#if SIZEOF_ST_INDEX_T*CHAR_BIT > 12*8
1404    hashseed <<= 32;
1405    hashseed |= genrand_int32(mt);
1406#endif
1407
1408    for (i = 0; i < numberof(sipseed.u32); ++i)
1409	sipseed.u32[i] = genrand_int32(mt);
1410
1411    rb_global_variable(&r->seed);
1412    r->seed = seed;
1413}
1414
1415st_index_t
1416rb_hash_start(st_index_t h)
1417{
1418    return st_hash_start(hashseed + h);
1419}
1420
1421st_index_t
1422rb_memhash(const void *ptr, long len)
1423{
1424    sip_uint64_t h = sip_hash24(sipseed.key, ptr, len);
1425#ifdef HAVE_UINT64_T
1426    return (st_index_t)h;
1427#else
1428    return (st_index_t)(h.u32[0] ^ h.u32[1]);
1429#endif
1430}
1431
1432static void
1433Init_RandomSeed2(void)
1434{
1435    VALUE seed = default_rand.seed;
1436
1437    if (RB_TYPE_P(seed, T_BIGNUM)) {
1438	RBASIC(seed)->klass = rb_cBignum;
1439    }
1440}
1441
1442void
1443rb_reset_random_seed(void)
1444{
1445    rb_random_t *r = &default_rand;
1446    uninit_genrand(&r->mt);
1447    r->seed = INT2FIX(0);
1448}
1449
1450/*
1451 * Document-class: Random
1452 *
1453 * Random provides an interface to Ruby's pseudo-random number generator, or
1454 * PRNG.  The PRNG produces a deterministic sequence of bits which approximate
1455 * true randomness. The sequence may be represented by integers, floats, or
1456 * binary strings.
1457 *
1458 * The generator may be initialized with either a system-generated or
1459 * user-supplied seed value by using Random.srand.
1460 *
1461 * The class method Random.rand provides the base functionality of Kernel.rand
1462 * along with better handling of floating point values. These are both
1463 * interfaces to Random::DEFAULT, the Ruby system PRNG.
1464 *
1465 * Random.new will create a new PRNG with a state independent of
1466 * Random::DEFAULT, allowing multiple generators with different seed values or
1467 * sequence positions to exist simultaneously. Random objects can be
1468 * marshaled, allowing sequences to be saved and resumed.
1469 *
1470 * PRNGs are currently implemented as a modified Mersenne Twister with a period
1471 * of 2**19937-1.
1472 */
1473
1474void
1475Init_Random(void)
1476{
1477    Init_RandomSeed2();
1478    rb_define_global_function("srand", rb_f_srand, -1);
1479    rb_define_global_function("rand", rb_f_rand, -1);
1480
1481    rb_cRandom = rb_define_class("Random", rb_cObject);
1482    rb_define_alloc_func(rb_cRandom, random_alloc);
1483    rb_define_method(rb_cRandom, "initialize", random_init, -1);
1484    rb_define_method(rb_cRandom, "rand", random_rand, -1);
1485    rb_define_method(rb_cRandom, "bytes", random_bytes, 1);
1486    rb_define_method(rb_cRandom, "seed", random_get_seed, 0);
1487    rb_define_method(rb_cRandom, "initialize_copy", random_copy, 1);
1488    rb_define_private_method(rb_cRandom, "marshal_dump", random_dump, 0);
1489    rb_define_private_method(rb_cRandom, "marshal_load", random_load, 1);
1490    rb_define_private_method(rb_cRandom, "state", random_state, 0);
1491    rb_define_private_method(rb_cRandom, "left", random_left, 0);
1492    rb_define_method(rb_cRandom, "==", random_equal, 1);
1493
1494    {
1495	VALUE rand_default = TypedData_Wrap_Struct(rb_cRandom, &random_data_type, &default_rand);
1496	rb_gc_register_mark_object(rand_default);
1497	rb_define_const(rb_cRandom, "DEFAULT", rand_default);
1498    }
1499
1500    rb_define_singleton_method(rb_cRandom, "srand", rb_f_srand, -1);
1501    rb_define_singleton_method(rb_cRandom, "rand", random_s_rand, -1);
1502    rb_define_singleton_method(rb_cRandom, "new_seed", random_seed, 0);
1503    rb_define_private_method(CLASS_OF(rb_cRandom), "state", random_s_state, 0);
1504    rb_define_private_method(CLASS_OF(rb_cRandom), "left", random_s_left, 0);
1505
1506    id_rand = rb_intern("rand");
1507    id_bytes = rb_intern("bytes");
1508}
1509