Class: Random
| Relationships & Source Files | |
| Namespace Children | |
| Modules: | |
| Super Chains via Extension / Inclusion / Inheritance | |
| Class Chain: 
          self,
           Formatter | |
| Instance Chain: 
          self,
           Formatter | |
| Inherits: | Object | 
| Defined in: | random.c, random.c | 
Overview
Random provides an interface to Ruby’s pseudo-random number generator, or PRNG.  The PRNG produces a deterministic sequence of bits which approximate true randomness. The sequence may be represented by integers, floats, or binary strings.
The generator may be initialized with either a system-generated or user-supplied seed value by using .srand.
The class method .rand provides the base functionality of Kernel.rand along with better handling of floating point values. These are both interfaces to DEFAULT, the Ruby system PRNG.
.new will create a new PRNG with a state independent of DEFAULT, allowing multiple generators with different seed values or sequence positions to exist simultaneously. Random objects can be marshaled, allowing sequences to be saved and resumed.
PRNGs are currently implemented as a modified Mersenne Twister with a period of 2**19937-1.
Constant Summary
- 
    DEFAULT =
    # File 'random.c', line 1557The default Pseudorandom number generator. Used by class methods of Random.rand_default
Class Method Summary
- 
    
      .bytes(size)  ⇒ String 
    
    Returns a random binary string. 
- 
    
      .new(seed = Random.new_seed)  ⇒ prng 
    
    constructor
    Creates a new PRNG using #seed to set the initial state. 
- 
    
      .new_seed  ⇒ Integer 
    
    Returns an arbitrary seed value. 
- 
    
      .rand  ⇒ Float 
    
    Alias of Random::DEFAULT.rand.
- 
    
      .srand(number = Random.new_seed)  ⇒ old_seed 
    
    Alias for Kernel.srand. 
- 
    
      .urandom(size)  ⇒ String 
    
    Returns a string, using platform providing features. 
Formatter - Extended
| rand | Generates formatted random number from raw random bytes. | 
| random_number | Alias for Formatter#rand. | 
Instance Method Summary
- 
    
      #==(prng2)  ⇒ Boolean 
    
    Returns true if the two generators have the same internal state, otherwise false. 
- 
    
      #bytes(size)  ⇒ String 
    
    Returns a random binary string containing sizebytes.
- 
    
      #rand  ⇒ Float 
    
    When maxis an::Integer,randreturns a random integer greater than or equal to zero and less thanmax.
- 
    
      #seed  ⇒ Integer 
    
    Returns the seed value used to initialize the generator. 
- #initialize_copy(orig) Internal use only
- #left private Internal use only
- #marshal_dump private Internal use only
- #marshal_load(dump) private Internal use only
- #state private Internal use only
Formatter - Included
| #rand | Generates formatted random number from raw random bytes. | 
| #random_number | Alias for Formatter#rand. | 
Constructor Details
    .new(seed = Random.new_seed)  ⇒ prng   
# File 'random.c', line 260
static VALUE
random_init(int argc, VALUE *argv, VALUE obj)
{
    VALUE vseed;
    rb_random_t *rnd = get_rnd(obj);
    if (rb_check_arity(argc, 0, 1) == 0) {
	rb_check_frozen(obj);
        vseed = random_seed(obj);
    }
    else {
	vseed = argv[0];
	rb_check_copyable(obj, vseed);
	vseed = rb_to_int(vseed);
    }
    rnd->seed = rand_init(&rnd->mt, vseed);
    return obj;
}
  Class Method Details
.bytes(size) ⇒ String
Returns a random binary string. The argument size specifies the length of the returned string.
# File 'random.c', line 1040
static VALUE
random_s_bytes(VALUE obj, VALUE len)
{
    rb_random_t *rnd = rand_start(&default_rand);
    return genrand_bytes(rnd, NUM2LONG(rb_to_int(len)));
}
  .new_seed ⇒ Integer
Returns an arbitrary seed value. This is used by .new when no seed value is specified as an argument.
Random.new_seed  #=> 115032730400174366788466674494640623225# File 'random.c', line 504
static VALUE
random_seed(VALUE _)
{
    VALUE v;
    uint32_t buf[DEFAULT_SEED_CNT+1];
    fill_random_seed(buf, DEFAULT_SEED_CNT);
    v = make_seed_value(buf, DEFAULT_SEED_CNT);
    explicit_bzero(buf, DEFAULT_SEED_LEN);
    return v;
}
  Alias of Random::DEFAULT.rand.
# File 'random.c', line 1392
static VALUE
random_s_rand(int argc, VALUE *argv, VALUE obj)
{
    VALUE v = rand_random(argc, argv, Qnil, rand_start(&default_rand));
    check_random_number(v, argv);
    return v;
}
  
    .srand(number = Random.new_seed)  ⇒ old_seed   
Alias for Kernel.srand.
.urandom(size) ⇒ String
Returns a string, using platform providing features. Returned value is expected to be a cryptographically secure pseudo-random number in binary form. This method raises a ::RuntimeError if the feature provided by platform failed to prepare the result.
In 2017, Linux manpage random(7) writes that “no cryptographic primitive available today can hope to promise more than 256 bits of security”. So it might be questionable to pass size > 32 to this method.
Random.urandom(8)  #=> "\x78\x41\xBA\xAF\x7D\xEA\xD8\xEA"# File 'random.c', line 531
static VALUE
random_raw_seed(VALUE self, VALUE size)
{
    long n = NUM2ULONG(size);
    VALUE buf = rb_str_new(0, n);
    if (n == 0) return buf;
    if (fill_random_bytes(RSTRING_PTR(buf), n, TRUE))
	rb_raise(rb_eRuntimeError, "failed to get urandom");
    return buf;
}
  Instance Method Details
    #==(prng2)  ⇒ Boolean   
Returns true if the two generators have the same internal state, otherwise false. Equivalent generators will return the same sequence of pseudo-random numbers. Two generators will generally have the same state only if they were initialized with the same seed
Random.new == Random.new             # => false
Random.new(1234) == Random.new(1234) # => trueand have the same invocation history.
prng1 = Random.new(1234)
prng2 = Random.new(1234)
prng1 == prng2 # => true
prng1.rand     # => 0.1915194503788923
prng1 == prng2 # => false
prng2.rand     # => 0.1915194503788923
prng1 == prng2 # => true# File 'random.c', line 1322
static VALUE
random_equal(VALUE self, VALUE other)
{
    rb_random_t *r1, *r2;
    if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse;
    r1 = get_rnd(self);
    r2 = get_rnd(other);
    if (memcmp(r1->mt.state, r2->mt.state, sizeof(r1->mt.state))) return Qfalse;
    if ((r1->mt.next - r1->mt.state) != (r2->mt.next - r2->mt.state)) return Qfalse;
    if (r1->mt.left != r2->mt.left) return Qfalse;
    return rb_equal(r1->seed, r2->seed);
}
  #bytes(size) ⇒ String
Returns a random binary string containing size bytes.
random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO"
random_string.size                   # => 10# File 'random.c', line 991
static VALUE
random_bytes(VALUE obj, VALUE len)
{
    return genrand_bytes(get_rnd(obj), NUM2LONG(rb_to_int(len)));
}
  #initialize_copy(orig)
# File 'random.c', line 563
static VALUE
random_copy(VALUE obj, VALUE orig)
{
    rb_random_t *rnd1, *rnd2;
    struct MT *mt;
    if (!OBJ_INIT_COPY(obj, orig)) return obj;
    rnd1 = get_rnd(obj);
    rnd2 = get_rnd(orig);
    mt = &rnd1->mt;
    *rnd1 = *rnd2;
    mt->next = mt->state + numberof(mt->state) - mt->left + 1;
    return obj;
}
  #left (private)
# File 'random.c', line 604
static VALUE
random_left(VALUE obj)
{
    rb_random_t *rnd = get_rnd(obj);
    return INT2FIX(rnd->mt.left);
}
  #marshal_dump (private)
# File 'random.c', line 619
static VALUE
random_dump(VALUE obj)
{
    rb_random_t *rnd = get_rnd(obj);
    VALUE dump = rb_ary_new2(3);
    rb_ary_push(dump, mt_state(&rnd->mt));
    rb_ary_push(dump, INT2FIX(rnd->mt.left));
    rb_ary_push(dump, rnd->seed);
    return dump;
}
  #marshal_load(dump) (private)
# File 'random.c', line 633
static VALUE
random_load(VALUE obj, VALUE dump)
{
    rb_random_t *rnd = get_rnd(obj);
    struct MT *mt = &rnd->mt;
    VALUE state, left = INT2FIX(1), seed = INT2FIX(0);
    unsigned long x;
    rb_check_copyable(obj, dump);
    Check_Type(dump, T_ARRAY);
    switch (RARRAY_LEN(dump)) {
      case 3:
        seed = RARRAY_AREF(dump, 2);
      case 2:
        left = RARRAY_AREF(dump, 1);
      case 1:
        state = RARRAY_AREF(dump, 0);
	break;
      default:
	rb_raise(rb_eArgError, "wrong dump data");
    }
    rb_integer_pack(state, mt->state, numberof(mt->state),
        sizeof(*mt->state), 0,
        INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
    x = NUM2ULONG(left);
    if (x > numberof(mt->state)) {
	rb_raise(rb_eArgError, "wrong value");
    }
    mt->left = (unsigned int)x;
    mt->next = mt->state + numberof(mt->state) - x + 1;
    rnd->seed = rb_to_int(seed);
    return obj;
}
  When max is an ::Integer, rand returns a random integer greater than or equal to zero and less than max. Unlike Kernel.rand, when max is a negative integer or zero, rand raises an ::ArgumentError.
prng = Random.new
prng.rand(100)       # => 42When max is a ::Float, rand returns a random floating point number between 0.0 and max, including 0.0 and excluding max.
prng.rand(1.5)       # => 1.4600282860034115When max is a ::Range, rand returns a random number where range.member?(number) == true.
prng.rand(5..9)      # => one of [5, 6, 7, 8, 9]
prng.rand(5...9)     # => one of [5, 6, 7, 8]
prng.rand(5.0..9.0)  # => between 5.0 and 9.0, including 9.0
prng.rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0Both the beginning and ending values of the range must respond to subtract (-) and add (+)methods, or rand will raise an ::ArgumentError.
# File 'random.c', line 1241
static VALUE
random_rand(int argc, VALUE *argv, VALUE obj)
{
    VALUE v = rand_random(argc, argv, obj, get_rnd(obj));
    check_random_number(v, argv);
    return v;
}
  #seed ⇒ Integer
Returns the seed value used to initialize the generator. This may be used to initialize another generator with the same state at a later time, causing it to produce the same sequence of numbers.
prng1 = Random.new(1234)
prng1.seed       #=> 1234
prng1.rand(100)  #=> 47
prng2 = Random.new(prng1.seed)
prng2.rand(100)  #=> 47# File 'random.c', line 556
static VALUE
random_get_seed(VALUE obj)
{
    return get_rnd(obj)->seed;
}
  #state (private)
# File 'random.c', line 589
static VALUE
random_state(VALUE obj)
{
    rb_random_t *rnd = get_rnd(obj);
    return mt_state(&rnd->mt);
}