Rust CookBook第一篇:随机数

Rust CookBook第一篇:随机数

本文系转载,出处:http://llever.com/rust-cookbook-zh/algorithms/randomness.zh.html


一、生成随机数

通过rand::thread_rng,在随机数生成器rand::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>());
}

二、生成范围内的随机数

Rng::gen_range,在半开[0, 10)区间内(不包括10)生成随机值。

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

三、生成给定分布的随机数

默认情况下,随机数有均匀(Uniform) 分布。要使用其他(概率/类型的)分布生成数字,您需要实例化一个分布(distribution),然后用分布下的Distribution::sample方法,在随机数生成器rand::Rng的帮助下,进行采样。

关于可用分布的文档,在此。下面是,一个使用Normal分布的的例子。

extern crate rand;

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

fn main() {
  let mut rng = rand::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)
}

四、生成自定义类型的随机值

随机生成一个元组(i32, bool, f64),和用户定义类型的变量Point。在 Point 类型之上,对Standard实现Distribution trait,为Point允许随机生成gen

这里用的是具象化泛型类型。

extern crate rand;

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

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

// 把 泛型 具象化为 Point, (定义实现)
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(); 
    // 主要是 : Point,类型标签,让编译器知道 (调用上面的实现定义)
    println!("Random tuple: {:?}", rand_tuple);
    println!("Random Point: {:?}", rand_point);
}

五、从一组字母+数字的字符,创建随机密码

随机生成,给定长度的 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);
}

六、从一组用户定义的字符,创建随机密码

使用用户自定义的字节字符串,随机生成给定长度的 ASCII 字符串,运用gen_range

extern crate rand;

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());
            // 这是安全的,因为 `idx` 会在 `CHARSET` 的范围内。
            char::from(unsafe { *CHARSET.get_unchecked(idx) }) // 来自用户的所有输入,最好都定义为不安全的。
        })
        .collect();

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值