Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

random.c
Go to the documentation of this file.
1 /**********************************************************************
2
3 random.c -
4
5 $Author$
6 created at: Fri Dec 24 16:39:21 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10 **********************************************************************/
11
12 #include "internal.h"
13
14 #include <limits.h>
15 #ifdef HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
18 #include <time.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #ifdef HAVE_FCNTL_H
22 #include <fcntl.h>
23 #endif
24 #include <math.h>
25 #include <errno.h>
26 #if defined(HAVE_SYS_TIME_H)
27 #include <sys/time.h>
28 #endif
29
30 #ifdef HAVE_SYSCALL_H
31 #include <syscall.h>
32 #elif defined HAVE_SYS_SYSCALL_H
33 #include <sys/syscall.h>
34 #endif
35
36 #ifdef _WIN32
37 #include <windows.h>
38 #include <wincrypt.h>
39 #endif
40 #include "ruby_atomic.h"
41
42 #ifdef __OpenBSD__
43 /* to define OpenBSD for version check */
44 #include <sys/param.h>
45 #endif
46
47 typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
48
49 #include "missing/mt19937.c"
50
51 /* generates a random number on [0,1) with 53-bit resolution*/
52 static double int_pair_to_real_exclusive(uint32_t a, uint32_t b);
53 static double
54 genrand_real(struct MT *mt)
55 {
56 /* mt must be initialized */
57 unsigned int a = genrand_int32(mt), b = genrand_int32(mt);
58 return int_pair_to_real_exclusive(a, b);
59 }
60
61 static double
62 int_pair_to_real_exclusive(uint32_t a, uint32_t b)
63 {
64 a >>= 5;
65 b >>= 6;
66 return(a*67108864.0+b)*(1.0/9007199254740992.0);
67 }
68
69 /* generates a random number on [0,1] with 53-bit resolution*/
70 static double int_pair_to_real_inclusive(uint32_t a, uint32_t b);
71 #if 0
72 static double
73 genrand_real2(struct MT *mt)
74 {
75 /* mt must be initialized */
76 uint32_t a = genrand_int32(mt), b = genrand_int32(mt);
77 return int_pair_to_real_inclusive(a, b);
78 }
79 #endif
80
81 /* These real versions are due to Isaku Wada, 2002/01/09 added */
82
83 #undef N
84 #undef M
85
86 typedef struct {
87 VALUE seed;
88 struct MT mt;
89 } rb_random_t;
90
91 #define DEFAULT_SEED_CNT 4
92
93 static rb_random_t default_rand;
94
95 static VALUE rand_init(struct MT *mt, VALUE vseed);
96 static VALUE random_seed(VALUE);
97
98 static rb_random_t *
99 rand_start(rb_random_t *r)
100 {
101 struct MT *mt = &r->mt;
102 if (!genrand_initialized(mt)) {
103 r->seed = rand_init(mt, random_seed(Qundef));
104 }
105 return r;
106 }
107
108 static struct MT *
109 default_mt(void)
110 {
111 return &rand_start(&default_rand)->mt;
112 }
113
114 unsigned int
115 rb_genrand_int32(void)
116 {
117 struct MT *mt = default_mt();
118 return genrand_int32(mt);
119 }
120
121 double
122 rb_genrand_real(void)
123 {
124 struct MT *mt = default_mt();
125 return genrand_real(mt);
126 }
127
128 #define SIZEOF_INT32 (31/CHAR_BIT + 1)
129
130 static double
131 int_pair_to_real_inclusive(uint32_t a, uint32_t b)
132 {
133 double r;
134 enum {dig = 53};
135 enum {dig_u = dig-32, dig_r64 = 64-dig, bmask = ~(~0u<<(dig_r64))};
136 #if defined HAVE_UINT128_T
137 const uint128_t m = ((uint128_t)1 << dig) | 1;
138 uint128_t x = ((uint128_t)a << 32) | b;
139 r = (double)(uint64_t)((x * m) >> 64);
140 #elif defined HAVE_UINT64_T && !(defined _MSC_VER && _MSC_VER <= 1200)
141 uint64_t x = ((uint64_t)a << dig_u) +
142 (((uint64_t)b + (a >> dig_u)) >> dig_r64);
143 r = (double)x;
144 #else
145 /* shift then add to get rid of overflow */
146 b = (b >> dig_r64) + (((a >> dig_u) + (b & bmask)) >> dig_r64);
147 r = (double)a * (1 << dig_u) + b;
148 #endif
149 return ldexp(r, -dig);
150 }
151
152 VALUE rb_cRandom;
153 #define id_minus '-'
154 #define id_plus '+'
155 static ID id_rand, id_bytes;
156 NORETURN(static void domain_error(void));
157
158 /* :nodoc: */
159 static void
160 random_mark(void *ptr)
161 {
162 rb_gc_mark(((rb_random_t *)ptr)->seed);
163 }
164
165 static void
166 random_free(void *ptr)
167 {
168 if (ptr != &default_rand)
169 xfree(ptr);
170 }
171
172 static size_t
173 random_memsize(const void *ptr)
174 {
175 return sizeof(rb_random_t);
176 }
177
178 static const rb_data_type_t random_mt_type = {
179 "random/MT",
180 {
181 random_mark,
182 random_free,
183 random_memsize,
184 },
185 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
186 };
187
188 static rb_random_t *
189 get_rnd(VALUE obj)
190 {
191 rb_random_t *ptr;
192 TypedData_Get_Struct(obj, rb_random_t, &random_mt_type, ptr);
193 return rand_start(ptr);
194 }
195
196 static rb_random_t *
197 try_get_rnd(VALUE obj)
198 {
199 if (obj == rb_cRandom) {
200 return rand_start(&default_rand);
201 }
202 if (!rb_typeddata_is_kind_of(obj, &random_mt_type)) return NULL;
203 return rand_start(DATA_PTR(obj));
204 }
205
206 /* :nodoc: */
207 static VALUE
208 random_alloc(VALUE klass)
209 {
210 rb_random_t *rnd;
211 VALUE obj = TypedData_Make_Struct(klass, rb_random_t, &random_mt_type, rnd);
212 rnd->seed = INT2FIX(0);
213 return obj;
214 }
215
216 static VALUE
217 rand_init(struct MT *mt, VALUE seed)
218 {
219 uint32_t buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0;
220 size_t len;
221 int sign;
222
223 len = rb_absint_numwords(seed, 32, NULL);
224 if (len > numberof(buf0))
225 buf = ALLOC_N(uint32_t, len);
226 sign = rb_integer_pack(seed, buf, len, sizeof(uint32_t), 0,
227 INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
228 if (sign < 0)
229 sign = -sign;
230 if (len == 0) {
231 buf[0] = 0;
232 len = 1;
233 }
234 if (len <= 1) {
235 init_genrand(mt, buf[0]);
236 }
237 else {
238 if (sign != 2 && buf[len-1] == 1) /* remove leading-zero-guard */
239 len--;
240 init_by_array(mt, buf, (int)len);
241 }
242 explicit_bzero(buf, len * sizeof(*buf));
243 if (buf != buf0) xfree(buf);
244 return seed;
245 }
246
247 /*
248 * call-seq:
249 * Random.new(seed = Random.new_seed) -> prng
250 *
251 * Creates a new PRNG using +seed+ to set the initial state. If +seed+ is
252 * omitted, the generator is initialized with Random.new_seed.
253 *
254 * See Random.srand for more information on the use of seed values.
255 */
256 static VALUE
257 random_init(int argc, VALUE *argv, VALUE obj)
258 {
259 VALUE vseed;
260 rb_random_t *rnd = get_rnd(obj);
261
262 if (rb_check_arity(argc, 0, 1) == 0) {
263 rb_check_frozen(obj);
264 vseed = random_seed(obj);
265 }
266 else {
267 vseed = argv[0];
268 rb_check_copyable(obj, vseed);
269 vseed = rb_to_int(vseed);
270 }
271 rnd->seed = rand_init(&rnd->mt, vseed);
272 return obj;
273 }
274
275 #define DEFAULT_SEED_LEN (DEFAULT_SEED_CNT * (int)sizeof(int32_t))
276
277 #if defined(S_ISCHR) && !defined(DOSISH)
278 # define USE_DEV_URANDOM 1
279 #else
280 # define USE_DEV_URANDOM 0
281 #endif
282
283 #if USE_DEV_URANDOM
284 static int
285 fill_random_bytes_urandom(void *seed, size_t size)
286 {
287 /*
288 O_NONBLOCK and O_NOCTTY is meaningless if /dev/urandom correctly points
289 to a urandom device. But it protects from several strange hazard if
290 /dev/urandom is not a urandom device.
291 */
292 int fd = rb_cloexec_open("/dev/urandom",
293 # ifdef O_NONBLOCK
294 O_NONBLOCK|
295 # endif
296 # ifdef O_NOCTTY
297 O_NOCTTY|
298 # endif
299 O_RDONLY, 0);
300 struct stat statbuf;
301 ssize_t ret = 0;
302 size_t offset = 0;
303
304 if (fd < 0) return -1;
305 rb_update_max_fd(fd);
306 if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
307 do {
308 ret = read(fd, ((char*)seed) + offset, size - offset);
309 if (ret < 0) {
310 close(fd);
311 return -1;
312 }
313 offset += (size_t)ret;
314 } while (offset < size);
315 }
316 close(fd);
317 return 0;
318 }
319 #else
320 # define fill_random_bytes_urandom(seed, size) -1
321 #endif
322
323 #if defined HAVE_GETRANDOM
324 # include <sys/random.h>
325 #elif defined __linux__ && defined __NR_getrandom
326 # include <linux/random.h>
327
328 # ifndef GRND_NONBLOCK
329 # define GRND_NONBLOCK 0x0001 /* not defined in musl libc */
330 # endif
331 # define getrandom(ptr, size, flags) \
332 (ssize_t)syscall(__NR_getrandom, (ptr), (size), (flags))
333 # define HAVE_GETRANDOM 1
334 #endif
335
336 #if 0
337 #elif defined MAC_OS_X_VERSION_10_7 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
338 #include <Security/Security.h>
339
340 static int
341 fill_random_bytes_syscall(void *seed, size_t size, int unused)
342 {
343 int status = SecRandomCopyBytes(kSecRandomDefault, size, seed);
344
345 if (status != errSecSuccess) {
346 # if 0
347 CFStringRef s = SecCopyErrorMessageString(status, NULL);
348 const char *m = s ? CFStringGetCStringPtr(s, kCFStringEncodingUTF8) : NULL;
349 fprintf(stderr, "SecRandomCopyBytes failed: %d: %s\n", status,
350 m ? m : "unknown");
351 if (s) CFRelease(s);
352 # endif
353 return -1;
354 }
355 return 0;
356 }
357 #elif defined(HAVE_ARC4RANDOM_BUF)
358 static int
359 fill_random_bytes_syscall(void *buf, size_t size, int unused)
360 {
361 #if (defined(__OpenBSD__) && OpenBSD >= 201411) || \
362 (defined(__NetBSD__) && __NetBSD_Version__ >= 700000000) || \
363 (defined(__FreeBSD__) && __FreeBSD_version >= 1200079)
364 arc4random_buf(buf, size);
365 return 0;
366 #else
367 return -1;
368 #endif
369 }
370 #elif defined(_WIN32)
371 static void
372 release_crypt(void *p)
373 {
374 HCRYPTPROV prov = (HCRYPTPROV)ATOMIC_PTR_EXCHANGE(*(HCRYPTPROV *)p, INVALID_HANDLE_VALUE);
375 if (prov && prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
376 CryptReleaseContext(prov, 0);
377 }
378 }
379
380 static int
381 fill_random_bytes_syscall(void *seed, size_t size, int unused)
382 {
383 static HCRYPTPROV perm_prov;
384 HCRYPTPROV prov = perm_prov, old_prov;
385 if (!prov) {
386 if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
387 prov = (HCRYPTPROV)INVALID_HANDLE_VALUE;
388 }
389 old_prov = (HCRYPTPROV)ATOMIC_PTR_CAS(perm_prov, 0, prov);
390 if (LIKELY(!old_prov)) { /* no other threads acquired */
391 if (prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
392 rb_gc_register_mark_object(Data_Wrap_Struct(0, 0, release_crypt, &perm_prov));
393 }
394 }
395 else { /* another thread acquired */
396 if (prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
397 CryptReleaseContext(prov, 0);
398 }
399 prov = old_prov;
400 }
401 }
402 if (prov == (HCRYPTPROV)INVALID_HANDLE_VALUE) return -1;
403 CryptGenRandom(prov, size, seed);
404 return 0;
405 }
406 #elif defined HAVE_GETRANDOM
407 static int
408 fill_random_bytes_syscall(void *seed, size_t size, int need_secure)
409 {
410 static rb_atomic_t try_syscall = 1;
411 if (try_syscall) {
412 size_t offset = 0;
413 int flags = 0;
414 if (!need_secure)
415 flags = GRND_NONBLOCK;
416 do {
417 errno = 0;
418 ssize_t ret = getrandom(((char*)seed) + offset, size - offset, flags);
419 if (ret == -1) {
420 ATOMIC_SET(try_syscall, 0);
421 return -1;
422 }
423 offset += (size_t)ret;
424 } while (offset < size);
425 return 0;
426 }
427 return -1;
428 }
429 #else
430 # define fill_random_bytes_syscall(seed, size, need_secure) -1
431 #endif
432
433 int
434 ruby_fill_random_bytes(void *seed, size_t size, int need_secure)
435 {
436 int ret = fill_random_bytes_syscall(seed, size, need_secure);
437 if (ret == 0) return ret;
438 return fill_random_bytes_urandom(seed, size);
439 }
440
441 #define fill_random_bytes ruby_fill_random_bytes
442
443 static void
444 fill_random_seed(uint32_t *seed, size_t cnt)
445 {
446 static int n = 0;
447 #if defined HAVE_CLOCK_GETTIME
448 struct timespec tv;
449 #elif defined HAVE_GETTIMEOFDAY
450 struct timeval tv;
451 #endif
452 size_t len = cnt * sizeof(*seed);
453
454 memset(seed, 0, len);
455
456 fill_random_bytes(seed, len, FALSE);
457
458 #if defined HAVE_CLOCK_GETTIME
459 clock_gettime(CLOCK_REALTIME, &tv);
460 seed[0] ^= tv.tv_nsec;
461 #elif defined HAVE_GETTIMEOFDAY
462 gettimeofday(&tv, 0);
463 seed[0] ^= tv.tv_usec;
464 #endif
465 seed[1] ^= (uint32_t)tv.tv_sec;
466 #if SIZEOF_TIME_T > SIZEOF_INT
467 seed[0] ^= (uint32_t)((time_t)tv.tv_sec >> SIZEOF_INT * CHAR_BIT);
468 #endif
469 seed[2] ^= getpid() ^ (n++ << 16);
470 seed[3] ^= (uint32_t)(VALUE)&seed;
471 #if SIZEOF_VOIDP > SIZEOF_INT
472 seed[2] ^= (uint32_t)((VALUE)&seed >> SIZEOF_INT * CHAR_BIT);
473 #endif
474 }
475
476 static VALUE
477 make_seed_value(uint32_t *ptr, size_t len)
478 {
479 VALUE seed;
480
481 if (ptr[len-1] <= 1) {
482 /* set leading-zero-guard */
483 ptr[len++] = 1;
484 }
485
486 seed = rb_integer_unpack(ptr, len, sizeof(uint32_t), 0,
487 INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
488
489 return seed;
490 }
491
492 /*
493 * call-seq: Random.new_seed -> integer
494 *
495 * Returns an arbitrary seed value. This is used by Random.new
496 * when no seed value is specified as an argument.
497 *
498 * Random.new_seed #=> 115032730400174366788466674494640623225
499 */
500 static VALUE
501 random_seed(VALUE _)
502 {
503 VALUE v;
504 uint32_t buf[DEFAULT_SEED_CNT+1];
505 fill_random_seed(buf, DEFAULT_SEED_CNT);
506 v = make_seed_value(buf, DEFAULT_SEED_CNT);
507 explicit_bzero(buf, DEFAULT_SEED_LEN);
508 return v;
509 }
510
511 /*
512 * call-seq: Random.urandom(size) -> string
513 *
514 * Returns a string, using platform providing features.
515 * Returned value is expected to be a cryptographically secure
516 * pseudo-random number in binary form.
517 * This method raises a RuntimeError if the feature provided by platform
518 * failed to prepare the result.
519 *
520 * In 2017, Linux manpage random(7) writes that "no cryptographic
521 * primitive available today can hope to promise more than 256 bits of
522 * security". So it might be questionable to pass size > 32 to this
523 * method.
524 *
525 * Random.urandom(8) #=> "\x78\x41\xBA\xAF\x7D\xEA\xD8\xEA"
526 */
527 static VALUE
528 random_raw_seed(VALUE self, VALUE size)
529 {
530 long n = NUM2ULONG(size);
531 VALUE buf = rb_str_new(0, n);
532 if (n == 0) return buf;
533 if (fill_random_bytes(RSTRING_PTR(buf), n, TRUE))
534 rb_raise(rb_eRuntimeError, "failed to get urandom");
535 return buf;
536 }
537
538 /*
539 * call-seq: prng.seed -> integer
540 *
541 * Returns the seed value used to initialize the generator. This may be used to
542 * initialize another generator with the same state at a later time, causing it
543 * to produce the same sequence of numbers.
544 *
545 * prng1 = Random.new(1234)
546 * prng1.seed #=> 1234
547 * prng1.rand(100) #=> 47
548 *
549 * prng2 = Random.new(prng1.seed)
550 * prng2.rand(100) #=> 47
551 */
552 static VALUE
553 random_get_seed(VALUE obj)
554 {
555 return get_rnd(obj)->seed;
556 }
557
558 /* :nodoc: */
559 static VALUE
560 random_copy(VALUE obj, VALUE orig)
561 {
562 rb_random_t *rnd1, *rnd2;
563 struct MT *mt;
564
565 if (!OBJ_INIT_COPY(obj, orig)) return obj;
566
567 rnd1 = get_rnd(obj);
568 rnd2 = get_rnd(orig);
569 mt = &rnd1->mt;
570
571 *rnd1 = *rnd2;
572 mt->next = mt->state + numberof(mt->state) - mt->left + 1;
573 return obj;
574 }
575
576 static VALUE
577 mt_state(const struct MT *mt)
578 {
579 return rb_integer_unpack(mt->state, numberof(mt->state),
580 sizeof(*mt->state), 0,
581 INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
582 }
583
584 /* :nodoc: */
585 static VALUE
586 random_state(VALUE obj)
587 {
588 rb_random_t *rnd = get_rnd(obj);
589 return mt_state(&rnd->mt);
590 }
591
592 /* :nodoc: */
593 static VALUE
594 random_s_state(VALUE klass)
595 {
596 return mt_state(&default_rand.mt);
597 }
598
599 /* :nodoc: */
600 static VALUE
601 random_left(VALUE obj)
602 {
603 rb_random_t *rnd = get_rnd(obj);
604 return INT2FIX(rnd->mt.left);
605 }
606
607 /* :nodoc: */
608 static VALUE
609 random_s_left(VALUE klass)
610 {
611 return INT2FIX(default_rand.mt.left);
612 }
613
614 /* :nodoc: */
615 static VALUE
616 random_dump(VALUE obj)
617 {
618 rb_random_t *rnd = get_rnd(obj);
619 VALUE dump = rb_ary_new2(3);
620
621 rb_ary_push(dump, mt_state(&rnd->mt));
622 rb_ary_push(dump, INT2FIX(rnd->mt.left));
623 rb_ary_push(dump, rnd->seed);
624
625 return dump;
626 }
627
628 /* :nodoc: */
629 static VALUE
630 random_load(VALUE obj, VALUE dump)
631 {
632 rb_random_t *rnd = get_rnd(obj);
633 struct MT *mt = &rnd->mt;
634 VALUE state, left = INT2FIX(1), seed = INT2FIX(0);
635 unsigned long x;
636
637 rb_check_copyable(obj, dump);
638 Check_Type(dump, T_ARRAY);
639 switch (RARRAY_LEN(dump)) {
640 case 3:
641 seed = RARRAY_AREF(dump, 2);
642 case 2:
643 left = RARRAY_AREF(dump, 1);
644 case 1:
645 state = RARRAY_AREF(dump, 0);
646 break;
647 default:
648 rb_raise(rb_eArgError, "wrong dump data");
649 }
650 rb_integer_pack(state, mt->state, numberof(mt->state),
651 sizeof(*mt->state), 0,
652 INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
653 x = NUM2ULONG(left);
654 if (x > numberof(mt->state)) {
655 rb_raise(rb_eArgError, "wrong value");
656 }
657 mt->left = (unsigned int)x;
658 mt->next = mt->state + numberof(mt->state) - x + 1;
659 rnd->seed = rb_to_int(seed);
660
661 return obj;
662 }
663
664 /*
665 * call-seq:
666 * srand(number = Random.new_seed) -> old_seed
667 *
668 * Seeds the system pseudo-random number generator, Random::DEFAULT, with
669 * +number+. The previous seed value is returned.
670 *
671 * If +number+ is omitted, seeds the generator using a source of entropy
672 * provided by the operating system, if available (/dev/urandom on Unix systems
673 * or the RSA cryptographic provider on Windows), which is then combined with
674 * the time, the process id, and a sequence number.
675 *
676 * srand may be used to ensure repeatable sequences of pseudo-random numbers
677 * between different runs of the program. By setting the seed to a known value,
678 * programs can be made deterministic during testing.
679 *
680 * srand 1234 # => 268519324636777531569100071560086917274
681 * [ rand, rand ] # => [0.1915194503788923, 0.6221087710398319]
682 * [ rand(10), rand(1000) ] # => [4, 664]
683 * srand 1234 # => 1234
684 * [ rand, rand ] # => [0.1915194503788923, 0.6221087710398319]
685 */
686
687 static VALUE
688 rb_f_srand(int argc, VALUE *argv, VALUE obj)
689 {
690 VALUE seed, old;
691 rb_random_t *r = &default_rand;
692
693 if (rb_check_arity(argc, 0, 1) == 0) {
694 seed = random_seed(obj);
695 }
696 else {
697 seed = rb_to_int(argv[0]);
698 }
699 old = r->seed;
700 r->seed = rand_init(&r->mt, seed);
701
702 return old;
703 }
704
705 static unsigned long
706 make_mask(unsigned long x)
707 {
708 x = x | x >> 1;
709 x = x | x >> 2;
710 x = x | x >> 4;
711 x = x | x >> 8;
712 x = x | x >> 16;
713 #if 4 < SIZEOF_LONG
714 x = x | x >> 32;
715 #endif
716 return x;
717 }
718
719 static unsigned long
720 limited_rand(struct MT *mt, unsigned long limit)
721 {
722 /* mt must be initialized */
723 unsigned long val, mask;
724
725 if (!limit) return 0;
726 mask = make_mask(limit);
727
728 #if 4 < SIZEOF_LONG
729 if (0xffffffff < limit) {
730 int i;
731 retry:
732 val = 0;
733 for (i = SIZEOF_LONG/SIZEOF_INT32-1; 0 <= i; i--) {
734 if ((mask >> (i * 32)) & 0xffffffff) {
735 val |= (unsigned long)genrand_int32(mt) << (i * 32);
736 val &= mask;
737 if (limit < val)
738 goto retry;
739 }
740 }
741 return val;
742 }
743 #endif
744
745 do {
746 val = genrand_int32(mt) & mask;
747 } while (limit < val);
748 return val;
749 }
750
751 static VALUE
752 limited_big_rand(struct MT *mt, VALUE limit)
753 {
754 /* mt must be initialized */
755
756 uint32_t mask;
757 long i;
758 int boundary;
759
760 size_t len;
761 uint32_t *tmp, *lim_array, *rnd_array;
762 VALUE vtmp;
763 VALUE val;
764
765 len = rb_absint_numwords(limit, 32, NULL);
766 tmp = ALLOCV_N(uint32_t, vtmp, len*2);
767 lim_array = tmp;
768 rnd_array = tmp + len;
769 rb_integer_pack(limit, lim_array, len, sizeof(uint32_t), 0,
770 INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
771
772 retry:
773 mask = 0;
774 boundary = 1;
775 for (i = len-1; 0 <= i; i--) {
776 uint32_t rnd;
777 uint32_t lim = lim_array[i];
778 mask = mask ? 0xffffffff : (uint32_t)make_mask(lim);
779 if (mask) {
780 rnd = genrand_int32(mt) & mask;
781 if (boundary) {
782 if (lim < rnd)
783 goto retry;
784 if (rnd < lim)
785 boundary = 0;
786 }
787 }
788 else {
789 rnd = 0;
790 }
791 rnd_array[i] = rnd;
792 }
793 val = rb_integer_unpack(rnd_array, len, sizeof(uint32_t), 0,
794 INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
795 ALLOCV_END(vtmp);
796
797 return val;
798 }
799
800 /*
801 * Returns random unsigned long value in [0, +limit+].
802 *
803 * Note that +limit+ is included, and the range of the argument and the
804 * return value depends on environments.
805 */
806 unsigned long
807 rb_genrand_ulong_limited(unsigned long limit)
808 {
809 return limited_rand(default_mt(), limit);
810 }
811
812 static VALUE
813 obj_random_bytes(VALUE obj, void *p, long n)
814 {
815 VALUE len = LONG2NUM(n);
816 VALUE v = rb_funcallv_public(obj, id_bytes, 1, &len);
817 long l;
818 Check_Type(v, T_STRING);
819 l = RSTRING_LEN(v);
820 if (l < n)
821 rb_raise(rb_eRangeError, "random data too short %ld", l);
822 else if (l > n)
823 rb_raise(rb_eRangeError, "random data too long %ld", l);
824 if (p) memcpy(p, RSTRING_PTR(v), n);
825 return v;
826 }
827
828 static unsigned int
829 random_int32(rb_random_t *rnd)
830 {
831 return genrand_int32(&rnd->mt);
832 }
833
834 unsigned int
835 rb_random_int32(VALUE obj)
836 {
837 rb_random_t *rnd = try_get_rnd(obj);
838 if (!rnd) {
839 uint32_t x;
840 obj_random_bytes(obj, &x, sizeof(x));
841 return (unsigned int)x;
842 }
843 return random_int32(rnd);
844 }
845
846 static double
847 random_real(VALUE obj, rb_random_t *rnd, int excl)
848 {
849 uint32_t a, b;
850
851 if (!rnd) {
852 uint32_t x[2] = {0, 0};
853 obj_random_bytes(obj, x, sizeof(x));
854 a = x[0];
855 b = x[1];
856 }
857 else {
858 a = random_int32(rnd);
859 b = random_int32(rnd);
860 }
861 if (excl) {
862 return int_pair_to_real_exclusive(a, b);
863 }
864 else {
865 return int_pair_to_real_inclusive(a, b);
866 }
867 }
868
869 double
870 rb_random_real(VALUE obj)
871 {
872 rb_random_t *rnd = try_get_rnd(obj);
873 if (!rnd) {
874 VALUE v = rb_funcallv(obj, id_rand, 0, 0);
875 double d = NUM2DBL(v);
876 if (d < 0.0) {
877 rb_raise(rb_eRangeError, "random number too small %g", d);
878 }
879 else if (d >= 1.0) {
880 rb_raise(rb_eRangeError, "random number too big %g", d);
881 }
882 return d;
883 }
884 return genrand_real(&rnd->mt);
885 }
886
887 static inline VALUE
888 ulong_to_num_plus_1(unsigned long n)
889 {
890 #if HAVE_LONG_LONG
891 return ULL2NUM((LONG_LONG)n+1);
892 #else
893 if (n >= ULONG_MAX) {
894 return rb_big_plus(ULONG2NUM(n), INT2FIX(1));
895 }
896 return ULONG2NUM(n+1);
897 #endif
898 }
899
900 static unsigned long
901 random_ulong_limited(VALUE obj, rb_random_t *rnd, unsigned long limit)
902 {
903 if (!limit) return 0;
904 if (!rnd) {
905 const int w = sizeof(limit) * CHAR_BIT - nlz_long(limit);
906 const int n = w > 32 ? sizeof(unsigned long) : sizeof(uint32_t);
907 const unsigned long mask = ~(~0UL << w);
908 const unsigned long full =
909 (size_t)n >= sizeof(unsigned long) ? ~0UL :
910 ~(~0UL << n * CHAR_BIT);
911 unsigned long val, bits = 0, rest = 0;
912 do {
913 if (mask & ~rest) {
914 union {uint32_t u32; unsigned long ul;} buf;
915 obj_random_bytes(obj, &buf, n);
916 rest = full;
917 bits = (n == sizeof(uint32_t)) ? buf.u32 : buf.ul;
918 }
919 val = bits;
920 bits >>= w;
921 rest >>= w;
922 val &= mask;
923 } while (limit < val);
924 return val;
925 }
926 return limited_rand(&rnd->mt, limit);
927 }
928
929 unsigned long
930 rb_random_ulong_limited(VALUE obj, unsigned long limit)
931 {
932 rb_random_t *rnd = try_get_rnd(obj);
933 if (!rnd) {
934 VALUE lim = ulong_to_num_plus_1(limit);
935 VALUE v = rb_to_int(rb_funcallv_public(obj, id_rand, 1, &lim));
936 unsigned long r = NUM2ULONG(v);
937 if (rb_num_negative_p(v)) {
938 rb_raise(rb_eRangeError, "random number too small %ld", r);
939 }
940 if (r > limit) {
941 rb_raise(rb_eRangeError, "random number too big %ld", r);
942 }
943 return r;
944 }
945 return limited_rand(&rnd->mt, limit);
946 }
947
948 static VALUE
949 random_ulong_limited_big(VALUE obj, rb_random_t *rnd, VALUE vmax)
950 {
951 if (!rnd) {
952 VALUE v, vtmp;
953 size_t i, nlz, len = rb_absint_numwords(vmax, 32, &nlz);
954 uint32_t *tmp = ALLOCV_N(uint32_t, vtmp, len * 2);
955 uint32_t mask = (uint32_t)~0 >> nlz;
956 uint32_t *lim_array = tmp;
957 uint32_t *rnd_array = tmp + len;
958 int flag = INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER;
959 rb_integer_pack(vmax, lim_array, len, sizeof(uint32_t), 0, flag);
960
961 retry:
962 obj_random_bytes(obj, rnd_array, len * sizeof(uint32_t));
963 rnd_array[0] &= mask;
964 for (i = 0; i < len; ++i) {
965 if (lim_array[i] < rnd_array[i])
966 goto retry;
967 if (rnd_array[i] < lim_array[i])
968 break;
969 }
970 v = rb_integer_unpack(rnd_array, len, sizeof(uint32_t), 0, flag);
971 ALLOCV_END(vtmp);
972 return v;
973 }
974 return limited_big_rand(&rnd->mt, vmax);
975 }
976
977 static VALUE genrand_bytes(rb_random_t *rnd, long n);
978
979 /*
980 * call-seq: prng.bytes(size) -> string
981 *
982 * Returns a random binary string containing +size+ bytes.
983 *
984 * random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO"
985 * random_string.size # => 10
986 */
987 static VALUE
988 random_bytes(VALUE obj, VALUE len)
989 {
990 return genrand_bytes(get_rnd(obj), NUM2LONG(rb_to_int(len)));
991 }
992
993 static VALUE
994 genrand_bytes(rb_random_t *rnd, long n)
995 {
996 VALUE bytes;
997 char *ptr;
998 unsigned int r, i;
999
1000 bytes = rb_str_new(0, n);
1001 ptr = RSTRING_PTR(bytes);
1002 for (; n >= SIZEOF_INT32; n -= SIZEOF_INT32) {
1003 r = genrand_int32(&rnd->mt);
1004 i = SIZEOF_INT32;
1005 do {
1006 *ptr++ = (char)r;
1007 r >>= CHAR_BIT;
1008 } while (--i);
1009 }
1010 if (n > 0) {
1011 r = genrand_int32(&rnd->mt);
1012 do {
1013 *ptr++ = (char)r;
1014 r >>= CHAR_BIT;
1015 } while (--n);
1016 }
1017 return bytes;
1018 }
1019
1020 VALUE
1021 rb_random_bytes(VALUE obj, long n)
1022 {
1023 rb_random_t *rnd = try_get_rnd(obj);
1024 if (!rnd) {
1025 return obj_random_bytes(obj, NULL, n);
1026 }
1027 return genrand_bytes(rnd, n);
1028 }
1029
1030 /*
1031 * call-seq: Random.bytes(size) -> string
1032 *
1033 * Returns a random binary string.
1034 * The argument +size+ specifies the length of the returned string.
1035 */
1036 static VALUE
1037 random_s_bytes(VALUE obj, VALUE len)
1038 {
1039 rb_random_t *rnd = rand_start(&default_rand);
1040 return genrand_bytes(rnd, NUM2LONG(rb_to_int(len)));
1041 }
1042
1043 static VALUE
1044 range_values(VALUE vmax, VALUE *begp, VALUE *endp, int *exclp)
1045 {
1046 VALUE beg, end;
1047
1048 if (!rb_range_values(vmax, &beg, &end, exclp)) return Qfalse;
1049 if (begp) *begp = beg;
1050 if (NIL_P(beg)) return Qnil;
1051 if (endp) *endp = end;
1052 if (NIL_P(end)) return Qnil;
1053 return rb_check_funcall_default(end, id_minus, 1, begp, Qfalse);
1054 }
1055
1056 static VALUE
1057 rand_int(VALUE obj, rb_random_t *rnd, VALUE vmax, int restrictive)
1058 {
1059 /* mt must be initialized */
1060 unsigned long r;
1061
1062 if (FIXNUM_P(vmax)) {
1063 long max = FIX2LONG(vmax);
1064 if (!max) return Qnil;
1065 if (max < 0) {
1066 if (restrictive) return Qnil;
1067 max = -max;
1068 }
1069 r = random_ulong_limited(obj, rnd, (unsigned long)max - 1);
1070 return ULONG2NUM(r);
1071 }
1072 else {
1073 VALUE ret;
1074 if (rb_bigzero_p(vmax)) return Qnil;
1075 if (!BIGNUM_SIGN(vmax)) {
1076 if (restrictive) return Qnil;
1077 vmax = rb_big_uminus(vmax);
1078 }
1079 vmax = rb_big_minus(vmax, INT2FIX(1));
1080 if (FIXNUM_P(vmax)) {
1081 long max = FIX2LONG(vmax);
1082 if (max == -1) return Qnil;
1083 r = random_ulong_limited(obj, rnd, max);
1084 return LONG2NUM(r);
1085 }
1086 ret = random_ulong_limited_big(obj, rnd, vmax);
1087 RB_GC_GUARD(vmax);
1088 return ret;
1089 }
1090 }
1091
1092 static void
1093 domain_error(void)
1094 {
1095 VALUE error = INT2FIX(EDOM);
1096 rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
1097 }
1098
1099 NORETURN(static void invalid_argument(VALUE));
1100 static void
1101 invalid_argument(VALUE arg0)
1102 {
1103 rb_raise(rb_eArgError, "invalid argument - %"PRIsVALUE, arg0);
1104 }
1105
1106 static VALUE
1107 check_random_number(VALUE v, const VALUE *argv)
1108 {
1109 switch (v) {
1110 case Qfalse:
1111 (void)NUM2LONG(argv[0]);
1112 break;
1113 case Qnil:
1114 invalid_argument(argv[0]);
1115 }
1116 return v;
1117 }
1118
1119 static inline double
1120 float_value(VALUE v)
1121 {
1122 double x = RFLOAT_VALUE(v);
1123 if (isinf(x) || isnan(x)) {
1124 domain_error();
1125 }
1126 return x;
1127 }
1128
1129 static inline VALUE
1130 rand_range(VALUE obj, rb_random_t* rnd, VALUE range)
1131 {
1132 VALUE beg = Qundef, end = Qundef, vmax, v;
1133 int excl = 0;
1134
1135 if ((v = vmax = range_values(range, &beg, &end, &excl)) == Qfalse)
1136 return Qfalse;
1137 if (NIL_P(v)) domain_error();
1138 if (!RB_TYPE_P(vmax, T_FLOAT) && (v = rb_check_to_int(vmax), !NIL_P(v))) {
1139 long max;
1140 vmax = v;
1141 v = Qnil;
1142 if (FIXNUM_P(vmax)) {
1143 fixnum:
1144 if ((max = FIX2LONG(vmax) - excl) >= 0) {
1145 unsigned long r = random_ulong_limited(obj, rnd, (unsigned long)max);
1146 v = ULONG2NUM(r);
1147 }
1148 }
1149 else if (BUILTIN_TYPE(vmax) == T_BIGNUM && BIGNUM_SIGN(vmax) && !rb_bigzero_p(vmax)) {
1150 vmax = excl ? rb_big_minus(vmax, INT2FIX(1)) : rb_big_norm(vmax);
1151 if (FIXNUM_P(vmax)) {
1152 excl = 0;
1153 goto fixnum;
1154 }
1155 v = random_ulong_limited_big(obj, rnd, vmax);
1156 }
1157 }
1158 else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
1159 int scale = 1;
1160 double max = RFLOAT_VALUE(v), mid = 0.5, r;
1161 if (isinf(max)) {
1162 double min = float_value(rb_to_float(beg)) / 2.0;
1163 max = float_value(rb_to_float(end)) / 2.0;
1164 scale = 2;
1165 mid = max + min;
1166 max -= min;
1167 }
1168 else if (isnan(max)) {
1169 domain_error();
1170 }
1171 v = Qnil;
1172 if (max > 0.0) {
1173 r = random_real(obj, rnd, excl);
1174 if (scale > 1) {
1175 return rb_float_new(+(+(+(r - 0.5) * max) * scale) + mid);
1176 }
1177 v = rb_float_new(r * max);
1178 }
1179 else if (max == 0.0 && !excl) {
1180 v = rb_float_new(0.0);
1181 }
1182 }
1183
1184 if (FIXNUM_P(beg) && FIXNUM_P(v)) {
1185 long x = FIX2LONG(beg) + FIX2LONG(v);
1186 return LONG2NUM(x);
1187 }
1188 switch (TYPE(v)) {
1189 case T_NIL:
1190 break;
1191 case T_BIGNUM:
1192 return rb_big_plus(v, beg);
1193 case T_FLOAT: {
1194 VALUE f = rb_check_to_float(beg);
1195 if (!NIL_P(f)) {
1196 return DBL2NUM(RFLOAT_VALUE(v) + RFLOAT_VALUE(f));
1197 }
1198 }
1199 default:
1200 return rb_funcallv(beg, id_plus, 1, &v);
1201 }
1202
1203 return v;
1204 }
1205
1206 static VALUE rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd);
1207
1208 /*
1209 * call-seq:
1210 * prng.rand -> float
1211 * prng.rand(max) -> number
1212 *
1213 * When +max+ is an Integer, +rand+ returns a random integer greater than
1214 * or equal to zero and less than +max+. Unlike Kernel.rand, when +max+
1215 * is a negative integer or zero, +rand+ raises an ArgumentError.
1216 *
1217 * prng = Random.new
1218 * prng.rand(100) # => 42
1219 *
1220 * When +max+ is a Float, +rand+ returns a random floating point number
1221 * between 0.0 and +max+, including 0.0 and excluding +max+.
1222 *
1223 * prng.rand(1.5) # => 1.4600282860034115
1224 *
1225 * When +max+ is a Range, +rand+ returns a random number where
1226 * range.member?(number) == true.
1227 *
1228 * prng.rand(5..9) # => one of [5, 6, 7, 8, 9]
1229 * prng.rand(5...9) # => one of [5, 6, 7, 8]
1230 * prng.rand(5.0..9.0) # => between 5.0 and 9.0, including 9.0
1231 * prng.rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0
1232 *
1233 * Both the beginning and ending values of the range must respond to subtract
1234 * (<tt>-</tt>) and add (<tt>+</tt>)methods, or rand will raise an
1235 * ArgumentError.
1236 */
1237 static VALUE
1238 random_rand(int argc, VALUE *argv, VALUE obj)
1239 {
1240 VALUE v = rand_random(argc, argv, obj, get_rnd(obj));
1241 check_random_number(v, argv);
1242 return v;
1243 }
1244
1245 static VALUE
1246 rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd)
1247 {
1248 VALUE vmax, v;
1249
1250 if (rb_check_arity(argc, 0, 1) == 0) {
1251 return rb_float_new(random_real(obj, rnd, TRUE));
1252 }
1253 vmax = argv[0];
1254 if (NIL_P(vmax)) return Qnil;
1255 if (!RB_TYPE_P(vmax, T_FLOAT)) {
1256 v = rb_check_to_int(vmax);
1257 if (!NIL_P(v)) return rand_int(obj, rnd, v, 1);
1258 }
1259 v = rb_check_to_float(vmax);
1260 if (!NIL_P(v)) {
1261 const double max = float_value(v);
1262 if (max < 0.0) {
1263 return Qnil;
1264 }
1265 else {
1266 double r = random_real(obj, rnd, TRUE);
1267 if (max > 0.0) r *= max;
1268 return rb_float_new(r);
1269 }
1270 }
1271 return rand_range(obj, rnd, vmax);
1272 }
1273
1274 /*
1275 * call-seq:
1276 * prng.random_number -> float
1277 * prng.random_number(max) -> number
1278 * prng.rand -> float
1279 * prng.rand(max) -> number
1280 *
1281 * Generates formatted random number from raw random bytes.
1282 * See Random#rand.
1283 */
1284 static VALUE
1285 rand_random_number(int argc, VALUE *argv, VALUE obj)
1286 {
1287 rb_random_t *rnd = try_get_rnd(obj);
1288 VALUE v = rand_random(argc, argv, obj, rnd);
1289 if (NIL_P(v)) v = rand_random(0, 0, obj, rnd);
1290 else if (!v) invalid_argument(argv[0]);
1291 return v;
1292 }
1293
1294 /*
1295 * call-seq:
1296 * prng1 == prng2 -> true or false
1297 *
1298 * Returns true if the two generators have the same internal state, otherwise
1299 * false. Equivalent generators will return the same sequence of
1300 * pseudo-random numbers. Two generators will generally have the same state
1301 * only if they were initialized with the same seed
1302 *
1303 * Random.new == Random.new # => false
1304 * Random.new(1234) == Random.new(1234) # => true
1305 *
1306 * and have the same invocation history.
1307 *
1308 * prng1 = Random.new(1234)
1309 * prng2 = Random.new(1234)
1310 * prng1 == prng2 # => true
1311 *
1312 * prng1.rand # => 0.1915194503788923
1313 * prng1 == prng2 # => false
1314 *
1315 * prng2.rand # => 0.1915194503788923
1316 * prng1 == prng2 # => true
1317 */
1318 static VALUE
1319 random_equal(VALUE self, VALUE other)
1320 {
1321 rb_random_t *r1, *r2;
1322 if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse;
1323 r1 = get_rnd(self);
1324 r2 = get_rnd(other);
1325 if (memcmp(r1->mt.state, r2->mt.state, sizeof(r1->mt.state))) return Qfalse;
1326 if ((r1->mt.next - r1->mt.state) != (r2->mt.next - r2->mt.state)) return Qfalse;
1327 if (r1->mt.left != r2->mt.left) return Qfalse;
1328 return rb_equal(r1->seed, r2->seed);
1329 }
1330
1331 /*
1332 * call-seq:
1333 * rand(max=0) -> number
1334 *
1335 * If called without an argument, or if <tt>max.to_i.abs == 0</tt>, rand
1336 * returns a pseudo-random floating point number between 0.0 and 1.0,
1337 * including 0.0 and excluding 1.0.
1338 *
1339 * rand #=> 0.2725926052826416
1340 *
1341 * When +max.abs+ is greater than or equal to 1, +rand+ returns a pseudo-random
1342 * integer greater than or equal to 0 and less than +max.to_i.abs+.
1343 *
1344 * rand(100) #=> 12
1345 *
1346 * When +max+ is a Range, +rand+ returns a random number where
1347 * range.member?(number) == true.
1348 *
1349 * Negative or floating point values for +max+ are allowed, but may give
1350 * surprising results.
1351 *
1352 * rand(-100) # => 87
1353 * rand(-0.5) # => 0.8130921818028143
1354 * rand(1.9) # equivalent to rand(1), which is always 0
1355 *
1356 * Kernel.srand may be used to ensure that sequences of random numbers are
1357 * reproducible between different runs of a program.
1358 *
1359 * See also Random.rand.
1360 */
1361
1362 static VALUE
1363 rb_f_rand(int argc, VALUE *argv, VALUE obj)
1364 {
1365 VALUE vmax;
1366 rb_random_t *rnd = rand_start(&default_rand);
1367
1368 if (rb_check_arity(argc, 0, 1) && !NIL_P(vmax = argv[0])) {
1369 VALUE v = rand_range(Qnil, rnd, vmax);
1370 if (v != Qfalse) return v;
1371 vmax = rb_to_int(vmax);
1372 if (vmax != INT2FIX(0)) {
1373 v = rand_int(Qnil, rnd, vmax, 0);
1374 if (!NIL_P(v)) return v;
1375 }
1376 }
1377 return DBL2NUM(genrand_real(&rnd->mt));
1378 }
1379
1380 /*
1381 * call-seq:
1382 * Random.rand -> float
1383 * Random.rand(max) -> number
1384 *
1385 * Alias of Random::DEFAULT.rand.
1386 */
1387
1388 static VALUE
1389 random_s_rand(int argc, VALUE *argv, VALUE obj)
1390 {
1391 VALUE v = rand_random(argc, argv, Qnil, rand_start(&default_rand));
1392 check_random_number(v, argv);
1393 return v;
1394 }
1395
1396 #define SIP_HASH_STREAMING 0
1397 #define sip_hash13 ruby_sip_hash13
1398 #if !defined _WIN32 && !defined BYTE_ORDER
1399 # ifdef WORDS_BIGENDIAN
1400 # define BYTE_ORDER BIG_ENDIAN
1401 # else
1402 # define BYTE_ORDER LITTLE_ENDIAN
1403 # endif
1404 # ifndef LITTLE_ENDIAN
1405 # define LITTLE_ENDIAN 1234
1406 # endif
1407 # ifndef BIG_ENDIAN
1408 # define BIG_ENDIAN 4321
1409 # endif
1410 #endif
1411 #include "siphash.c"
1412
1413 typedef struct {
1414 st_index_t hash;
1415 uint8_t sip[16];
1416 } seed_keys_t;
1417
1418 static union {
1419 seed_keys_t key;
1420 uint32_t u32[type_roomof(seed_keys_t, uint32_t)];
1421 } seed;
1422
1423 static void
1424 init_seed(struct MT *mt)
1425 {
1426 int i;
1427
1428 for (i = 0; i < numberof(seed.u32); ++i)
1429 seed.u32[i] = genrand_int32(mt);
1430 }
1431
1432 NO_SANITIZE("unsigned-integer-overflow", extern st_index_t rb_hash_start(st_index_t h));
1433 st_index_t
1434 rb_hash_start(st_index_t h)
1435 {
1436 return st_hash_start(seed.key.hash + h);
1437 }
1438
1439 st_index_t
1440 rb_memhash(const void *ptr, long len)
1441 {
1442 sip_uint64_t h = sip_hash13(seed.key.sip, ptr, len);
1443 #ifdef HAVE_UINT64_T
1444 return (st_index_t)h;
1445 #else
1446 return (st_index_t)(h.u32[0] ^ h.u32[1]);
1447 #endif
1448 }
1449
1450 /* Initialize Ruby internal seeds. This function is called at very early stage
1451 * of Ruby startup. Thus, you can't use Ruby's object. */
1452 void
1453 Init_RandomSeedCore(void)
1454 {
1455 /*
1456 Don't reuse this MT for Random::DEFAULT. Random::DEFAULT::seed shouldn't
1457 provide a hint that an attacker guess siphash's seed.
1458 */
1459 struct MT mt;
1460 uint32_t initial_seed[DEFAULT_SEED_CNT];
1461
1462 fill_random_seed(initial_seed, DEFAULT_SEED_CNT);
1463 init_by_array(&mt, initial_seed, DEFAULT_SEED_CNT);
1464
1465 init_seed(&mt);
1466
1467 explicit_bzero(initial_seed, DEFAULT_SEED_LEN);
1468 }
1469
1470 static VALUE
1471 init_randomseed(struct MT *mt)
1472 {
1473 uint32_t initial[DEFAULT_SEED_CNT+1];
1474 VALUE seed;
1475
1476 fill_random_seed(initial, DEFAULT_SEED_CNT);
1477 init_by_array(mt, initial, DEFAULT_SEED_CNT);
1478 seed = make_seed_value(initial, DEFAULT_SEED_CNT);
1479 explicit_bzero(initial, DEFAULT_SEED_LEN);
1480 return seed;
1481 }
1482
1483 /* construct Random::DEFAULT bits */
1484 static VALUE
1485 Init_Random_default(VALUE klass)
1486 {
1487 rb_random_t *r = &default_rand;
1488 struct MT *mt = &r->mt;
1489 VALUE v = TypedData_Wrap_Struct(klass, &random_mt_type, r);
1490
1491 rb_gc_register_mark_object(v);
1492 r->seed = init_randomseed(mt);
1493
1494 return v;
1495 }
1496
1497 void
1498 rb_reset_random_seed(void)
1499 {
1500 rb_random_t *r = &default_rand;
1501 uninit_genrand(&r->mt);
1502 r->seed = INT2FIX(0);
1503 }
1504
1505 /*
1506 * Document-class: Random
1507 *
1508 * Random provides an interface to Ruby's pseudo-random number generator, or
1509 * PRNG. The PRNG produces a deterministic sequence of bits which approximate
1510 * true randomness. The sequence may be represented by integers, floats, or
1511 * binary strings.
1512 *
1513 * The generator may be initialized with either a system-generated or
1514 * user-supplied seed value by using Random.srand.
1515 *
1516 * The class method Random.rand provides the base functionality of Kernel.rand
1517 * along with better handling of floating point values. These are both
1518 * interfaces to Random::DEFAULT, the Ruby system PRNG.
1519 *
1520 * Random.new will create a new PRNG with a state independent of
1521 * Random::DEFAULT, allowing multiple generators with different seed values or
1522 * sequence positions to exist simultaneously. Random objects can be
1523 * marshaled, allowing sequences to be saved and resumed.
1524 *
1525 * PRNGs are currently implemented as a modified Mersenne Twister with a period
1526 * of 2**19937-1.
1527 */
1528
1529 void
1530 InitVM_Random(void)
1531 {
1532 rb_define_global_function("srand", rb_f_srand, -1);
1533 rb_define_global_function("rand", rb_f_rand, -1);
1534
1535 rb_cRandom = rb_define_class("Random", rb_cObject);
1536 rb_define_alloc_func(rb_cRandom, random_alloc);
1537 rb_define_method(rb_cRandom, "initialize", random_init, -1);
1538 rb_define_method(rb_cRandom, "rand", random_rand, -1);
1539 rb_define_method(rb_cRandom, "bytes", random_bytes, 1);
1540 rb_define_method(rb_cRandom, "seed", random_get_seed, 0);
1541 rb_define_method(rb_cRandom, "initialize_copy", random_copy, 1);
1542 rb_define_private_method(rb_cRandom, "marshal_dump", random_dump, 0);
1543 rb_define_private_method(rb_cRandom, "marshal_load", random_load, 1);
1544 rb_define_private_method(rb_cRandom, "state", random_state, 0);
1545 rb_define_private_method(rb_cRandom, "left", random_left, 0);
1546 rb_define_method(rb_cRandom, "==", random_equal, 1);
1547
1548 {
1549 /* Direct access to Ruby's Pseudorandom number generator (PRNG). */
1550 VALUE rand_default = Init_Random_default(rb_cRandom);
1551 /* The default Pseudorandom number generator. Used by class
1552 * methods of Random. */
1553 rb_define_const(rb_cRandom, "DEFAULT", rand_default);
1554 }
1555
1556 rb_define_singleton_method(rb_cRandom, "srand", rb_f_srand, -1);
1557 rb_define_singleton_method(rb_cRandom, "rand", random_s_rand, -1);
1558 rb_define_singleton_method(rb_cRandom, "bytes", random_s_bytes, 1);
1559 rb_define_singleton_method(rb_cRandom, "new_seed", random_seed, 0);
1560 rb_define_singleton_method(rb_cRandom, "urandom", random_raw_seed, 1);
1561 rb_define_private_method(CLASS_OF(rb_cRandom), "state", random_s_state, 0);
1562 rb_define_private_method(CLASS_OF(rb_cRandom), "left", random_s_left, 0);
1563
1564 {
1565 /* Format raw random number as Random does */
1566 VALUE m = rb_define_module_under(rb_cRandom, "Formatter");
1567 rb_include_module(rb_cRandom, m);
1568 rb_extend_object(rb_cRandom, m);
1569 rb_define_method(m, "random_number", rand_random_number, -1);
1570 rb_define_method(m, "rand", rand_random_number, -1);
1571 }
1572 }
1573
1574 #undef rb_intern
1575 void
1576 Init_Random(void)
1577 {
1578 id_rand = rb_intern("rand");
1579 id_bytes = rb_intern("bytes");
1580
1581 InitVM(Random);
1582 }
ID
unsigned long ID
Definition: ruby.h:103
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
void
void
Definition: rb_mjit_min_header-2.7.0.h:13273
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1244
Check_Type
#define Check_Type(v, t)
Definition: ruby.h:595
TRUE
#define TRUE
Definition: nkf.h:175
stat
Definition: rb_mjit_min_header-2.7.0.h:2384
T_FLOAT
#define T_FLOAT
Definition: ruby.h:527
time_t
long time_t
Definition: rb_mjit_min_header-2.7.0.h:1236
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:869
r2
#define r2
explicit_bzero
RUBY_EXTERN void explicit_bzero(void *b, size_t len)
Definition: explicit_bzero.c:77
range
#define range(low, item, hi)
Definition: date_strftime.c:21
fstat
int fstat(int __fd, struct stat *__sbuf)
close
int close(int __fildes)
ATOMIC_PTR_EXCHANGE
#define ATOMIC_PTR_EXCHANGE(var, val)
Definition: ruby_atomic.h:186
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:7063
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:797
memset
void * memset(void *, int, size_t)
uint64_t
#define uint64_t
Definition: siphash.h:15
size_t
long unsigned int size_t
Definition: rb_mjit_min_header-2.7.0.h:666
rb_reset_random_seed
void rb_reset_random_seed(void)
Definition: random.c:1498
st_hash_start
#define st_hash_start(h)
Definition: st.h:184
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
MT::next
uint32_t * next
Definition: mt19937.c:65
id_minus
#define id_minus
Definition: random.c:153
NUM2LONG
#define NUM2LONG(x)
Definition: ruby.h:679
MT::left
int left
Definition: mt19937.c:66
LONG_LONG
#define LONG_LONG
Definition: rb_mjit_min_header-2.7.0.h:3939
O_NONBLOCK
#define O_NONBLOCK
Definition: win32.h:611
NUM2ULONG
#define NUM2ULONG(x)
Definition: ruby.h:689
fill_random_bytes_urandom
#define fill_random_bytes_urandom(seed, size)
Definition: random.c:320
mt19937.c
rb_equal
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
Definition: object.c:124
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_funcallv_public
VALUE rb_funcallv_public(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:980
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
type_roomof
#define type_roomof(x, y)
Definition: internal.h:1299
rb_intern
#define rb_intern(str)
rb_random_real
double rb_random_real(VALUE obj)
Definition: random.c:870
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
MT::state
uint32_t state[N]
Definition: mt19937.c:64
TYPE
#define TYPE(x)
Definition: ruby.h:554
SIZEOF_INT
#define SIZEOF_INT
Definition: rb_mjit_min_header-2.7.0.h:83
key
seed_keys_t key
Definition: random.c:1419
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
rb_num_negative_p
int rb_num_negative_p(VALUE)
Definition: numeric.c:313
old
VALUE ID VALUE old
Definition: rb_mjit_min_header-2.7.0.h:16133
sip_uint64_t
Definition: siphash.h:12
CLOCK_REALTIME
#define CLOCK_REALTIME
Definition: win32.h:133
rb_define_global_function
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1787
uint64_t
unsigned long long uint64_t
Definition: sha2.h:102
DEFAULT_SEED_CNT
#define DEFAULT_SEED_CNT
Definition: random.c:91
Init_Random
void Init_Random(void)
Definition: random.c:1576
Qundef
#define Qundef
Definition: ruby.h:470
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
CHAR_BIT
#define CHAR_BIT
Definition: ruby.h:227
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
Data_Wrap_Struct
#define Data_Wrap_Struct(klass, mark, free, sval)
Definition: ruby.h:1211
ptr
struct RIMemo * ptr
Definition: debug.c:74
Qfalse
#define Qfalse
Definition: ruby.h:467
DBL2NUM
#define DBL2NUM(dbl)
Definition: ruby.h:967
ssize_t
_ssize_t ssize_t
Definition: rb_mjit_min_header-2.7.0.h:1329
ATOMIC_PTR_CAS
#define ATOMIC_PTR_CAS(var, oldval, val)
Definition: ruby_atomic.h:201
NULL
#define NULL
Definition: _sdbm.c:101
S_ISCHR
#define S_ISCHR(m)
uint32_t
unsigned int uint32_t
Definition: sha2.h:101
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:394
error
const rb_iseq_t const char * error
Definition: rb_mjit_min_header-2.7.0.h:13506
ATOMIC_SET
#define ATOMIC_SET(var, val)
Definition: ruby_atomic.h:131
rb_check_arity
#define rb_check_arity
Definition: intern.h:347
InitVM
#define InitVM(ext)
Definition: ruby.h:2329
ULL2NUM
#define ULL2NUM(v)
Definition: rb_mjit_min_header-2.7.0.h:4242
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
ALLOC_N
#define ALLOC_N(type, n)
Definition: ruby.h:1663
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.0.h:7899
NO_SANITIZE
NO_SANITIZE("unsigned-integer-overflow", extern st_index_t rb_hash_start(st_index_t h))
rb_bigzero_p
int rb_bigzero_p(VALUE x)
Definition: bignum.c:2919
rb_big_uminus
VALUE rb_big_uminus(VALUE x)
Definition: bignum.c:5554
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_eRangeError
VALUE rb_eRangeError
Definition: error.c:926
rb_to_float
VALUE rb_to_float(VALUE)
Converts a Numeric object into Float.
Definition: object.c:3542
LONG2NUM
#define LONG2NUM(x)
Definition: ruby.h:1644
INTEGER_PACK_MSWORD_FIRST
#define INTEGER_PACK_MSWORD_FIRST
Definition: intern.h:151
SIZEOF_LONG
#define SIZEOF_LONG
Definition: rb_mjit_min_header-2.7.0.h:85
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
r1
#define r1
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
read
_ssize_t read(int __fd, void *__buf, size_t __nbyte)
arc4random_buf
void arc4random_buf(void *, size_t)
rb_integer_pack
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3547
id_plus
#define id_plus
Definition: random.c:154
rb_random_t::mt
struct MT mt
Definition: random.c:88
ULONG2NUM
#define ULONG2NUM(x)
Definition: ruby.h:1645
memcpy
void * memcpy(void *__restrict, const void *__restrict, size_t)
double
double
Definition: rb_mjit_min_header-2.7.0.h:5923
DATA_PTR
#define DATA_PTR(dta)
Definition: ruby.h:1175
fprintf
int fprintf(FILE *__restrict, const char *__restrict,...) __attribute__((__format__(__printf__
LIKELY
#define LIKELY(x)
Definition: ffi_common.h:125
ALLOCV_END
#define ALLOCV_END(v)
Definition: ruby.h:1750
rb_check_frozen
#define rb_check_frozen(obj)
Definition: intern.h:319
rb_random_t
Definition: random.c:86
ALLOCV_N
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1749
NORETURN
NORETURN(static void domain_error(void))
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
rb_random_int32
unsigned int rb_random_int32(VALUE obj)
Definition: random.c:835
mask
enum @11::@13::@14 mask
long
#define long
Definition: rb_mjit_min_header-2.7.0.h:2880
rb_genrand_real
double rb_genrand_real(void)
Definition: random.c:122
u32
uint32_t u32[type_roomof(seed_keys_t, uint32_t)]
Definition: random.c:1420
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
st_index_t
st_data_t st_index_t
Definition: st.h:50
rb_update_max_fd
void rb_update_max_fd(int fd)
Definition: io.c:218
cnt
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:503
TypedData_Wrap_Struct
#define TypedData_Wrap_Struct(klass, data_type, sval)
Definition: ruby.h:1231
stderr
#define stderr
Definition: rb_mjit_min_header-2.7.0.h:1485
SIZEOF_INT32
#define SIZEOF_INT32
Definition: random.c:128
isnan
#define isnan(x)
Definition: win32.h:369
rb_integer_unpack
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3633
INTEGER_PACK_NATIVE_BYTE_ORDER
#define INTEGER_PACK_NATIVE_BYTE_ORDER
Definition: intern.h:155
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
fill_random_bytes
#define fill_random_bytes
Definition: random.c:441
rb_random_bytes
VALUE rb_random_bytes(VALUE obj, long n)
Definition: random.c:1021
genrand_initialized
#define genrand_initialized(mt)
Definition: mt19937.c:69
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: ruby.h:1101
rb_big_minus
VALUE rb_big_minus(VALUE x, VALUE y)
Definition: bignum.c:5853
size
int size
Definition: encoding.c:58
uint8_t
unsigned char uint8_t
Definition: sha2.h:100
FALSE
#define FALSE
Definition: nkf.h:174
isinf
#define isinf(__x)
Definition: rb_mjit_min_header-2.7.0.h:3673
uint128_t
#define uint128_t
Definition: rb_mjit_min_header-2.7.0.h:235
FIXNUM_P
#define FIXNUM_P(f)
Definition: ruby.h:396
fill_random_bytes_syscall
#define fill_random_bytes_syscall(seed, size, need_secure)
Definition: random.c:430
rb_to_int
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3021
SIZEOF_TIME_T
#define SIZEOF_TIME_T
Definition: rb_mjit_min_header-2.7.0.h:93
rb_check_to_int
VALUE rb_check_to_int(VALUE)
Tries to convert val into Integer.
Definition: object.c:3036
stat::st_mode
mode_t st_mode
Definition: rb_mjit_min_header-2.7.0.h:2388
memcmp
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
getpid
pid_t getpid(void)
rb_extend_object
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1700
rb_random_t::seed
VALUE seed
Definition: random.c:87
rb_typeddata_is_kind_of
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:872
timeval::tv_sec
time_t tv_sec
Definition: missing.h:54
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:484
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
int_must_be_32bit_at_least
int int_must_be_32bit_at_least[sizeof(int) *CHAR_BIT< 32 ? -1 :1]
Definition: random.c:47
rb_genrand_int32
unsigned int rb_genrand_int32(void)
Definition: random.c:115
char
#define char
Definition: rb_mjit_min_header-2.7.0.h:2876
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
rb_cloexec_open
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
Definition: io.c:292
rb_ary_new2
#define rb_ary_new2
Definition: intern.h:103
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:667
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:533
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1252
internal.h
OBJ_INIT_COPY
#define OBJ_INIT_COPY(obj, orig)
Definition: intern.h:331
timeval::tv_usec
long tv_usec
Definition: missing.h:55
T_ARRAY
#define T_ARRAY
Definition: ruby.h:530
argv
char ** argv
Definition: ruby.c:223
f
#define f
rb_absint_numwords
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
Definition: bignum.c:3382
Init_RandomSeedCore
void Init_RandomSeedCore(void)
Definition: random.c:1453
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
T_NIL
#define T_NIL
Definition: ruby.h:522
timeval
Definition: missing.h:53
MT
Definition: mt19937.c:62
siphash.c
BIGNUM_SIGN
#define BIGNUM_SIGN(b)
Definition: internal.h:761
DEFAULT_SEED_LEN
#define DEFAULT_SEED_LEN
Definition: random.c:275
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
clock_gettime
int clock_gettime(clockid_t, struct timespec *)
Definition: win32.c:4612
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
rb_hash_start
st_index_t rb_hash_start(st_index_t h)
Definition: random.c:1434
argc
int argc
Definition: ruby.c:222
rb_big_plus
VALUE rb_big_plus(VALUE x, VALUE y)
Definition: bignum.c:5824
rb_check_funcall_default
VALUE rb_check_funcall_default(VALUE, ID, int, const VALUE *, VALUE)
Definition: vm_eval.c:533
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2880
rb_memhash
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1440
rb_eSystemCallError
VALUE rb_eSystemCallError
Definition: error.c:941
sip_hash13
#define sip_hash13
Definition: random.c:1397
rb_data_type_struct
Definition: ruby.h:1148
BUILTIN_TYPE
#define BUILTIN_TYPE(x)
Definition: ruby.h:551
rb_big_norm
VALUE rb_big_norm(VALUE x)
Definition: bignum.c:3152
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
Definition: ruby.h:966
xfree
#define xfree
Definition: defines.h:216
EDOM
#define EDOM
Definition: rb_mjit_min_header-2.7.0.h:10970
seed_keys_t::hash
st_index_t hash
Definition: random.c:1414
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6116
rb_gc_mark
void rb_gc_mark(VALUE ptr)
Definition: gc.c:5212
_
#define _(args)
Definition: dln.h:28
rb_range_values
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
Definition: range.c:1243
errno
int errno
rb_genrand_ulong_limited
unsigned long rb_genrand_ulong_limited(unsigned long limit)
Definition: random.c:807
len
uint8_t len
Definition: escape.c:17
rb_check_copyable
void rb_check_copyable(VALUE obj, VALUE orig)
Definition: error.c:3047
rb_class_new_instance
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
Definition: object.c:1955
timespec
Definition: missing.h:60
ruby_atomic.h
ULONG_MAX
#define ULONG_MAX
Definition: rb_mjit_min_header-2.7.0.h:4060
T_STRING
#define T_STRING
Definition: ruby.h:528
rb_atomic_t
int rb_atomic_t
Definition: ruby_atomic.h:124
seed_keys_t
Definition: random.c:1413
domain_error
#define domain_error(msg)
Definition: math.c:32
uninit_genrand
#define uninit_genrand(mt)
Definition: mt19937.c:70
Qnil
#define Qnil
Definition: ruby.h:469
NUM2DBL
#define NUM2DBL(x)
Definition: ruby.h:774
INTEGER_PACK_LSWORD_FIRST
#define INTEGER_PACK_LSWORD_FIRST
Definition: intern.h:152
h
size_t st_index_t h
Definition: rb_mjit_min_header-2.7.0.h:5462
rb_float_new
#define rb_float_new(d)
Definition: internal.h:1960
ruby_fill_random_bytes
int ruby_fill_random_bytes(void *seed, size_t size, int need_secure)
Definition: random.c:434
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: ruby.h:585
numberof
#define numberof(array)
Definition: etc.c:618
gettimeofday
int gettimeofday(struct timeval *, struct timezone *)
Definition: win32.c:4598
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
rb_define_private_method
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1569
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_random_ulong_limited
unsigned long rb_random_ulong_limited(VALUE obj, unsigned long limit)
Definition: random.c:930
rb_cRandom
VALUE rb_cRandom
Definition: random.c:152
InitVM_Random
void InitVM_Random(void)
Definition: random.c:1530
rb_check_to_float
VALUE rb_check_to_float(VALUE)
Tries to convert an object into Float.
Definition: object.c:3559
ldexp
double ldexp(double, int)