class Random
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 usingRandom.srand.
The class methodRandom.rand provides the base functionality ofKernel.rand along with better handling of floating point values. These are both interfaces to the Ruby system PRNG.
Random.new will create a new PRNG with a state independent of the Ruby system PRNG, 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. As this algorithm isnot for cryptographical use, you must useSecureRandom for security purpose, instead of this PRNG.
See alsoRandom::Formatter module that adds convenience methods to generate various forms of random data.
Public Class Methods
Source
static VALUErandom_s_bytes(VALUE obj, VALUE len){ rb_random_t *rnd = default_rand_start(); return rand_bytes(&random_mt_if, rnd, NUM2LONG(rb_to_int(len)));}Returns a random binary string. The argumentsize specifies the length of the returned string.
Source
static VALUErandom_init(int argc, VALUE *argv, VALUE obj){ const rb_random_interface_t *rng = NULL; rb_random_t *rnd = try_get_rnd(obj, &rng); if (!rng) { rb_raise(rb_eTypeError, "undefined random interface: %s", RTYPEDDATA_TYPE(obj)->wrap_struct_name); } unsigned int major = rng->version.major; unsigned int minor = rng->version.minor; if (major != RUBY_RANDOM_INTERFACE_VERSION_MAJOR) { rb_raise(rb_eTypeError, "Random interface version " STRINGIZE(RUBY_RANDOM_INTERFACE_VERSION_MAJOR) "." STRINGIZE(RUBY_RANDOM_INTERFACE_VERSION_MINOR) " " "expected: %d.%d", major, minor); } argc = rb_check_arity(argc, 0, 1); rb_check_frozen(obj); if (argc == 0) { RB_OBJ_WRITE(obj, &rnd->seed, rand_init_default(rng, rnd)); } else { RB_OBJ_WRITE(obj, &rnd->seed, rand_init(rng, rnd, rb_to_int(argv[0]))); } return obj;}Creates a new PRNG usingseed to set the initial state. Ifseed is omitted, the generator is initialized withRandom.new_seed.
SeeRandom.srand for more information on the use of seed values.
Source
static VALUErandom_seed(VALUE _){ VALUE v; with_random_seed(DEFAULT_SEED_CNT, 1, true) { v = make_seed_value(seedbuf, DEFAULT_SEED_CNT); } return v;}Returns an arbitrary seed value. This is used byRandom.new when no seed value is specified as an argument.
Random.new_seed#=> 115032730400174366788466674494640623225
Source
static VALUErandom_s_rand(int argc, VALUE *argv, VALUE obj){ VALUE v = rand_random(argc, argv, Qnil, &random_mt_if, default_rand_start()); check_random_number(v, argv); return v;}Returns a random number using the Ruby system PRNG.
See alsoRandom#rand.
Source
static VALUErandom_s_seed(VALUE obj){ rb_random_mt_t *rnd = default_mt(); return rnd->base.seed;}Returns the seed value used to initialize the Ruby system PRNG. 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.
Random.seed#=> 1234prng1 =Random.new(Random.seed)prng1.seed#=> 1234prng1.rand(100)#=> 47Random.seed#=> 1234Random.rand(100)#=> 47
Source
static VALUErb_f_srand(int argc, VALUE *argv, VALUE obj){ VALUE seed, old; rb_random_mt_t *r = default_mt(); if (rb_check_arity(argc, 0, 1) == 0) { seed = random_seed(obj); } else { seed = rb_to_int(argv[0]); } old = r->base.seed; rand_init(&random_mt_if, &r->base, seed); r->base.seed = seed; return old;}Seeds the system pseudo-random number generator, withnumber. The previous seed value is returned.
Ifnumber is omitted, seeds the generator using a source of entropy provided by the operating system, if available (/dev/urandom on Unix systems or the RSA cryptographic provider on Windows), which is then combined with the time, the process id, and a sequence number.
srand may be used to ensure repeatable sequences of pseudo-random numbers between different runs of the program. By setting the seed to a known value, programs can be made deterministic during testing.
srand1234# => 268519324636777531569100071560086917274[rand,rand ]# => [0.1915194503788923, 0.6221087710398319][rand(10),rand(1000) ]# => [4, 664]srand1234# => 1234[rand,rand ]# => [0.1915194503788923, 0.6221087710398319]
Source
static VALUErandom_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;}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 aRuntimeError 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"
Public Instance Methods
Source
static VALUErand_mt_equal(VALUE self, VALUE other){ rb_random_mt_t *r1, *r2; if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse; r1 = get_rnd_mt(self); r2 = get_rnd_mt(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->base.seed, r2->base.seed);}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# => falseRandom.new(1234)==Random.new(1234)# => true
and have the same invocation history.
prng1 =Random.new(1234)prng2 =Random.new(1234)prng1==prng2# => trueprng1.rand# => 0.1915194503788923prng1==prng2# => falseprng2.rand# => 0.1915194503788923prng1==prng2# => true
Source
static VALUErandom_bytes(VALUE obj, VALUE len){ const rb_random_interface_t *rng = NULL; rb_random_t *rnd = try_get_rnd(obj, &rng); return rand_bytes(rng, rnd, NUM2LONG(rb_to_int(len)));}Returns a random binary string containingsize bytes.
random_string =Random.new.bytes(10)# => "\xD7:R\xAB?\x83\xCE\xFAkO"random_string.size# => 10
Source
static VALUErandom_rand(int argc, VALUE *argv, VALUE obj){ const rb_random_interface_t *rng = NULL; rb_random_t *rnd = try_get_rnd(obj, &rng); VALUE v = rand_random(argc, argv, obj, rng, rnd); check_random_number(v, argv); return v;}Whenmax is anInteger,rand returns a random integer greater than or equal to zero and less thanmax. UnlikeKernel.rand, whenmax is a negative integer or zero,rand raises anArgumentError.
prng =Random.newprng.rand(100)# => 42
Whenmax is aFloat,rand returns a random floating point number between 0.0 andmax, including 0.0 and excludingmax. Note that it behaves differently fromKernel.rand.
prng.rand(1.5)# => 1.4600282860034115rand(1.5)# => 0
Whenrange is aRange,rand returns a random number whererange.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.0prng.rand(5.0...9.0)# => between 5.0 and 9.0, excluding 9.0
Both the beginning and ending values of the range must respond to subtract (-) and add (+)methods, or rand will raise anArgumentError.
Source
static VALUErandom_get_seed(VALUE obj){ return get_rnd(obj)->seed;}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#=> 1234prng1.rand(100)#=> 47prng2 =Random.new(prng1.seed)prng2.rand(100)#=> 47