Spec-Zone.ru › Ruby 3

класс Random

Родитель:
base

Random предоставляет интерфейс к псевдослучайному генератору чисел Руби, или PRNG. PRNG генерирует детерминированную последовательность битов, которые приближают истинную случайность. Последовательность может быть представлена целыми числами, числами с плавающей запятой или двоичными строками.

Генератор может быть инициализирован либо системным, либо заданным пользователем значением семени, используя Random.srand.

Метод класса Random.rand предоставляет базовые функциональные возможности Kernel.rand вместе с лучшим обращением с числами с плавающей запятой. Оба метода являются интерфейсами к системному PRNG Руби.

Random.new создаст новый PRNG с состоянием, независимым от системного PRNG Руби, позволяя одновременно существовать нескольким генераторам с различными значениями семян или позициями в последовательности. Объекты Random могут быть сериализованы, позволяя сохранять и возобновлять последовательности.

PRNG в настоящее время реализованы как модифицированный генератор Мерсенна-Твистера с периодом 2**19937-1. Поскольку этот алгоритм не предназначен для криптографического использования, для целей безопасности вы должны использовать SecureRandom, а не этот PRNG.

Константы

DEFAULT

Публичные методы класса

bytes(size) → string Показать исходный код
static VALUE
random_s_bytes(VALUE obj, VALUE len)
{
    rb_random_t *rnd = rand_start(default_rand());
    return rand_bytes(&random_mt_if, rnd, NUM2LONG(rb_to_int(len)));
}

Возвращает случайную двоичную строку. Аргумент size задает длину возвращаемой строки.

new(seed = Random.new_seed) → prng Показать исходный код
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);
    }
    argc = rb_check_arity(argc, 0, 1);
    rb_check_frozen(obj);
    if (argc == 0) {
        rnd->seed = rand_init_default(rng, rnd);
    }
    else {
        rnd->seed = rand_init(rng, rnd, rb_to_int(argv[0]));
    }
    return obj;
}

Создаёт новый PRNG, используя seed для установки начального состояния. Если seed опущено, генератор инициализируется с помощью Random.new_seed.

См. Random.srand для получения дополнительной информации об использовании значений семян.

new_seed → integer Показать исходный код
static VALUE
random_seed(VALUE _)
{
    VALUE v;
    with_random_seed(DEFAULT_SEED_CNT, 1) {
        v = make_seed_value(seedbuf, DEFAULT_SEED_CNT);
    }
    return v;
}

Возвращает произвольное значение семени. Оно используется методом Random.new, когда значение семени не указано в качестве аргумента.

Random.new_seed  #=> 115032730400174366788466674494640623225
rand → float Показать исходный код
rand(max) → number
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;
}
seed() Показать исходный код
static VALUE
random_s_seed(VALUE obj)
{
    rb_random_mt_t *rnd = rand_mt_start(default_rand());
    return rnd->base.seed;
}
srand(number = Random.new_seed) → old_seed Показать исходный код
static VALUE
rb_f_srand(int argc, VALUE *argv, VALUE obj)
{
    VALUE seed, old;
    rb_random_mt_t *r = rand_mt_start(default_rand());

    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;
}

Инициализирует системный псевдослучайный генератор чисел, используя number. Возвращает предыдущее значение семени.

Если number опущено, генератор инициализируется, используя источник энтропии, предоставляемый операционной системой (если доступен — /dev/urandom на системах Unix или криптографический модуль RSA на Windows), который затем комбинируется с временем, идентификатором процесса и порядковым номером.

srand может быть использован для обеспечения повторяемости последовательностей псевдослучайных чисел между различными запусками программы. Установив семя на известное значение, программы могут быть сделаны детерминированными во время тестирования.

srand 1234               # => 268519324636777531569100071560086917274
[ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
[ rand(10), rand(1000) ] # => [4, 664]
srand 1234               # => 1234
[ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
urandom(size) → string Показать исходный код
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;
}

Возвращает строку, используя возможности платформы. Ожидается, что возвращаемое значение будет криптографически безопасным псевдослучайным числом в двоичной форме. Этот метод вызывает исключение RuntimeError, если платформа не смогла подготовить результат.

В 2017 году в man-странице Linux random(7) было сказано, что «ни один криптографический примитив, доступный сегодня, не может гарантировать более чем 256 бит безопасности». Поэтому может быть сомнительно передавать размер > 32 в этот метод.

Random.urandom(8)  #=> "\x78\x41\xBA\xAF\x7D\xEA\xD8\xEA"

Публичные методы экземпляров

prng1 == prng2 → true or false Показать исходный код
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);
}

Возвращает true, если два генератора имеют одинаковое внутреннее состояние, иначе false. Эквивалентные генераторы вернут ту же последовательность псевдослучайных чисел. Два генератора обычно имеют одинаковое состояние только в том случае, если они были инициализированы одним и тем же семенем

Random.new == Random.new             # => false
Random.new(1234) == Random.new(1234) # => true

и имеют одинаковую историю вызовов.

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
bytes(size) → string Показать исходный код
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)));
}

Возвращает случайную двоичную строку, содержащую size байта.

random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO"
random_string.size                   # => 10
rand → float Показать исходный код
rand(max) → number
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;
}

Когда max является Integer, rand возвращает случайное целое число, большее или равное нулю и меньшее max. В отличие от Kernel.rand, когда max является отрицательным целым числом или нулем, rand вызывает исключение ArgumentError.

prng = Random.new
prng.rand(100)       # => 42

Когда max является Float, rand возвращает случайное число с плавающей запятой между 0.0 и max, включая 0.0 и исключая max.

prng.rand(1.5)       # => 1.4600282860034115

Когда max является Range, rand возвращает случайное число, где 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.0

Оба начальное и конечное значения диапазона должны отвечать методам вычитания (-) и сложения (+), в противном случае rand вызовет исключение ArgumentError.

seed → integer Показать исходный код
static VALUE
random_get_seed(VALUE obj)
{
    return get_rnd(obj)->seed;
}

Возвращает значение семени, используемое для инициализации генератора. Оно может быть использовано для инициализации другого генератора с тем же состоянием в более позднее время, вызывая генерацию той же последовательности чисел.

prng1 = Random.new(1234)
prng1.seed       #=> 1234
prng1.rand(100)  #=> 47

prng2 = Random.new(prng1.seed)
prng2.rand(100)  #=> 47

Ruby Core © 1993–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API