class Random
Random bietet eine Schnittstelle zum Pseudo-Zufallszahlengenerator (PRNG) von Ruby. Der PRNG erzeugt eine deterministische Bitfolge, die echte Zufälligkeit annähert. Die Sequenz kann durch ganze Zahlen, Gleitkommazahlen oder Binärzeichenketten dargestellt werden.
Der Generator kann mit einem systemgenerierten oder einem vom Benutzer bereitgestellten Startwert initialisiert werden, indem Random.srand verwendet wird.
Die Klassenmethode Random.rand bietet die Grundfunktionalität von Kernel.rand zusammen mit einer besseren Handhabung von Gleitkommawerten. Beides sind Schnittstellen zum Ruby-System-PRNG.
Random.new erstellt einen neuen PRNG mit einem Zustand, der unabhängig vom Ruby-System-PRNG ist, und ermöglicht so die gleichzeitige Existenz mehrerer Generatoren mit unterschiedlichen Startwerten oder Sequenzpositionen. Random-Objekte können gemarsht werden, was das Speichern und Wiederaufnehmen von Sequenzen ermöglicht.
PRNGs werden derzeit als modifizierter Mersenne Twister mit einer Periode von 2**19937-1 implementiert. Da dieser Algorithmus **nicht** für kryptographische Zwecke geeignet ist, müssen Sie für Sicherheitszwecke stattdessen SecureRandom anstelle dieses PRNG verwenden.
Siehe auch das Modul Random::Formatter, das Komfortmethoden zur Generierung verschiedener Formen von Zufallsdaten hinzufügt.
Öffentliche Klassenmethoden
Source
static VALUE
random_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)));
}
Gibt eine zufällige Binärzeichenkette zurück. Das Argument size gibt die Länge der zurückgegebenen Zeichenkette an.
Source
static VALUE
random_init(int argc, VALUE *argv, VALUE obj)
{
rb_random_t *rnd = try_get_rnd(obj);
const rb_random_interface_t *rng = rb_rand_if(obj);
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;
}
Erstellt einen neuen PRNG, der seed zur Festlegung des Anfangszustands verwendet. Wenn seed weggelassen wird, wird der Generator mit Random.new_seed initialisiert.
Siehe Random.srand für weitere Informationen zur Verwendung von Startwerten.
Source
static VALUE
random_seed(VALUE _)
{
VALUE v;
with_random_seed(DEFAULT_SEED_CNT, 1, true) {
v = make_seed_value(seedbuf, DEFAULT_SEED_CNT);
}
return v;
}
Gibt einen beliebigen Startwert zurück. Dieser wird von Random.new verwendet, wenn kein Startwert als Argument angegeben wird.
Random.new_seed #=> 115032730400174366788466674494640623225
Source
static VALUE
random_s_rand(int argc, VALUE *argv, VALUE obj)
{
VALUE v = rand_random(argc, argv, Qnil, default_rand_start());
check_random_number(v, argv);
return v;
}
Gibt eine Zufallszahl unter Verwendung des Ruby-System-PRNG zurück.
Siehe auch Random#rand.
Source
static VALUE
random_s_seed(VALUE obj)
{
rb_random_mt_t *rnd = default_mt();
return rnd->base.seed;
}
Gibt den Startwert zurück, der zur Initialisierung des Ruby-System-PRNG verwendet wurde. Dies kann verwendet werden, um einen anderen Generator zu einem späteren Zeitpunkt mit demselben Zustand zu initialisieren, wodurch die gleiche Zahlenfolge erzeugt wird.
Random.seed #=> 1234 prng1 = Random.new(Random.seed) prng1.seed #=> 1234 prng1.rand(100) #=> 47 Random.seed #=> 1234 Random.rand(100) #=> 47
Source
static VALUE
rb_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;
}
Initialisiert den systemeigenen Pseudo-Zufallszahlengenerator mit number. Der vorherige Startwert wird zurückgegeben.
Wenn number weggelassen wird, wird der Generator mit einer vom Betriebssystem bereitgestellten Entropiequelle (falls verfügbar, /dev/urandom unter Unix-Systemen oder der RSA-Kryptografieanbieter unter Windows) initialisiert, die dann mit der Zeit, der Prozess-ID und einer Sequenznummer kombiniert wird.
srand kann verwendet werden, um wiederholbare Sequenzen von Pseudo-Zufallszahlen zwischen verschiedenen Programm-Läufen zu gewährleisten. Durch Setzen des Startwerts auf einen bekannten Wert können Programme während des Testens deterministisch gemacht werden.
srand 1234 # => 268519324636777531569100071560086917274 [ rand, rand ] # => [0.1915194503788923, 0.6221087710398319] [ rand(10), rand(1000) ] # => [4, 664] srand 1234 # => 1234 [ rand, rand ] # => [0.1915194503788923, 0.6221087710398319]
Source
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;
}
Gibt eine Zeichenkette zurück, die plattformspezifische Funktionen nutzt. Der zurückgegebene Wert ist voraussichtlich eine kryptographisch sichere Pseudo-Zufallszahl in Binärform. Diese Methode löst eine RuntimeError aus, wenn die von der Plattform bereitgestellte Funktion das Ergebnis nicht vorbereiten konnte.
Im Jahr 2017 schreibt die Linux-Manpage random(7), dass „kein heute verfügbares kryptographisches Primitiv mehr als 256 Bit Sicherheit versprechen kann“. Daher kann es fraglich sein, size > 32 an diese Methode zu übergeben.
Random.urandom(8) #=> "\x78\x41\xBA\xAF\x7D\xEA\xD8\xEA"
Öffentliche Instanzmethoden
Source
static VALUE
rand_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);
}
Gibt true zurück, wenn die beiden Generatoren denselben internen Zustand haben, andernfalls false. Äquivalente Generatoren geben dieselbe Sequenz von Pseudo-Zufallszahlen zurück. Zwei Generatoren haben im Allgemeinen nur dann denselben Zustand, wenn sie mit demselben Startwert initialisiert wurden
Random.new == Random.new # => false Random.new(1234) == Random.new(1234) # => true
und dieselbe Aufrufhistorie haben.
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
Source
static VALUE
random_bytes(VALUE obj, VALUE len)
{
rb_random_t *rnd = try_get_rnd(obj);
return rand_bytes(rb_rand_if(obj), rnd, NUM2LONG(rb_to_int(len)));
}
Gibt eine zufällige Binärzeichenkette mit size Bytes zurück.
random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO" random_string.size # => 10
Source
static VALUE
random_rand(int argc, VALUE *argv, VALUE obj)
{
VALUE v = rand_random(argc, argv, obj, try_get_rnd(obj));
check_random_number(v, argv);
return v;
}
Wenn max eine Integer ist, gibt rand eine zufällige ganze Zahl größer oder gleich null und kleiner als max zurück. Im Gegensatz zu Kernel.rand löst rand eine ArgumentError aus, wenn max eine negative ganze Zahl oder null ist.
prng = Random.new prng.rand(100) # => 42
Wenn max ein Float ist, gibt rand eine zufällige Gleitkommazahl zwischen 0.0 und max zurück, einschließlich 0.0 und ausschließend max. Beachten Sie, dass dies anders funktioniert als Kernel.rand.
prng.rand(1.5) # => 1.4600282860034115 rand(1.5) # => 0
Wenn range ein Range ist, gibt rand eine Zufallszahl zurück, für die range.member?(number) == true gilt.
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.0
Sowohl der Anfangs- als auch der Endwert des Bereichs müssen die Subtraktions- (-) und Additions- (+) Methoden unterstützen, andernfalls löst rand eine ArgumentError aus.
Source
static VALUE
random_get_seed(VALUE obj)
{
return get_rnd(obj)->seed;
}
Gibt den Startwert zurück, der zur Initialisierung des Generators verwendet wurde. Dies kann verwendet werden, um einen anderen Generator zu einem späteren Zeitpunkt mit demselben Zustand zu initialisieren, wodurch die gleiche Zahlenfolge erzeugt wird.
prng1 = Random.new(1234) prng1.seed #=> 1234 prng1.rand(100) #=> 47 prng2 = Random.new(prng1.seed) prng2.rand(100) #=> 47