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