Генерация случайных значений

Генерация случайных чисел

rand-badge cat-science-badge

Пример генерирует случайные числа с помощью генератора (псевдо)случайных чисел rand::Rng полученного через rand::thread_rng. Каждый поток операционной системы имеет свой инициализированный генератор. Сгенерированные целые числа распределены равномерно на диапазоне, заданного их типом, а вещественные числа генерируются из диапазона от 0 до 1, не включая само число 1.

extern crate rand;

use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();

    let n1: u8 = rng.gen();
    let n2: u16 = rng.gen();
    println!("Random u8: {}", n1);
    println!("Random u16: {}", n2);
    println!("Random u32: {}", rng.gen::<u32>());
    println!("Random i32: {}", rng.gen::<i32>());
    println!("Random float: {}", rng.gen::<f64>());
}

Генерация случайных чисел из диапазона

rand-badge cat-science-badge

Пример генерирует случайные числа из полуоткрытого диапазона [0, 10) (не включающего 10) с помощью метода Rng::gen_range.

extern crate rand;

use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    println!("Integer: {}", rng.gen_range(0, 10));
    println!("Float: {}", rng.gen_range(0.0, 10.0));
}

Uniform задаёт равномерное распределение. Его использование работает точно так же, но может работать быстрее, когда нам нужно генерировать числа из данного диапазона много раз.

extern crate rand;


use rand::distributions::{Distribution, Uniform};

fn main() {
    let mut rng = rand::thread_rng();
    let die = Uniform::from(1..7);

    loop {
        let throw = die.sample(&mut rng);
        println!("Roll the die: {}", throw);
        if throw == 6 {
            break;
        }
    }
}

Генерация случайных числе с заданным распределением

[![rand_distr-badge]][rand_distr] cat-science-badge

По умолчанию, случайные числа из крейта rand имеют непрерывное равномерное распределение. Крейт rand_distr предоставляет другие типы распределений. Для их использования вы создаёте экземпляр распределения, затем элемент из этого распределения используя метод Distribution::sample с помощью генератора случайных чисел rand::Rng.

Доступные распределения описаны здесь. Пример использования нормального распределения Normal показан ниже.

use rand_distr::{Distribution, Normal, NormalError};
use rand::thread_rng;

fn main() -> Result<(), NormalError> {
    let mut rng = thread_rng();
    let normal = Normal::new(2.0, 3.0)?;
    let v = normal.sample(&mut rng);
    println!("{} is from a N(2, 9) distribution", v);
    Ok(())
}

Генерация случайных чисел пользовательского типа

rand-badge cat-science-badge

Пример случайно генерирует пару (i32, bool, f64) и переменную пользовательского типа Point. Реализует типаж Distribution от Point для особенного типа Standard для того, чтобы включить возможность случайной генерации значений Point.

extern crate rand;

use rand::Rng;
use rand::distributions::{Distribution, Standard};

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

impl Distribution<Point> for Standard {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Point {
        let (rand_x, rand_y) = rng.gen();
        Point {
            x: rand_x,
            y: rand_y,
        }
    }
}

fn main() {
    let mut rng = rand::thread_rng();
    let rand_tuple = rng.gen::<(i32, bool, f64)>();
    let rand_point: Point = rng.gen();
    println!("Random tuple: {:?}", rand_tuple);
    println!("Random Point: {:?}", rand_point);
}

Создание случайных паролей из букв и цифр

rand-badge cat-os-badge

Пример случайно генерирует строку с заданной длиной из ASCII символов из диапазона A-Z, a-z, 0-9 с помощью образца Alphanumeric.

extern crate rand;

use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;

fn main() {
    let rand_string: String = thread_rng()
        .sample_iter(&Alphanumeric)
        .take(30)
        .collect();

    println!("{}", rand_string);
}

Создание случайных паролей из заданного множества символов

rand-badge cat-os-badge

Пример случайно генерирует строку заданной длины из ASCII символов по заданному пользователем байтовой строки с помощью gen_range.

fn main() {
    use rand::Rng;
    const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
                            abcdefghijklmnopqrstuvwxyz\
                            0123456789)(*&^%$#@!~";
    const PASSWORD_LEN: usize = 30;
    let mut rng = rand::thread_rng();

    let password: String = (0..PASSWORD_LEN)
        .map(|_| {
            let idx = rng.gen_range(0, CHARSET.len());
            CHARSET[idx] as char
        })
        .collect();

    println!("{:?}", password);
}