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