Ruby: random.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

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