Rust生成随机值实战应用

生成随机数、随机字符、符合一定分布的抽样值,是日常开发中经常遇到的场景。本文解释Rust中相关的工具包。并通过示例说明如何生成随机值。

rand包

该包提供随机数生成器:rand::Rng, 其中的方法 rand::thread_rng 可以生成随机数,其中每个线程有相应的初始化生成器。使用之前需要加载依赖,在Cargo.toml文件中增加依赖,然后执行cargo build 加载依赖:

复制代码
[dependencies]
rand_distr = "0.4.3"
rand = "0.8.5"

rand包提供了随机数生成器,rand_distr是数据分布抽样的包,后面会提及。

生成随机数

rand包生成的整数符合在数据类型范围内的均匀分布;浮点数是0~1(不包括1)之间的均匀分布值。

rust 复制代码
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>());
}

// 输出结果参考:
//Random u8: 139
//Random u16: 61962
//Random u32: 3908588647
//Random i32: -1602019840
//Random float: 0.9836476488710262

生成范围内的随机数

使用Rng::gen_range方法,可以生成指定范围内的随机数,区间是半开的,如:[0, 10),不包括10:

rust 复制代码
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可以得到分布均匀的值。与前者效果相同,但在重复生成相同范围内的数字时可能会更快。

rust 复制代码
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包生成的随机数缺省基于均匀分布。rand_distr包提供了多种数据分布类型。我们可以实例化分布对象,然后使用其抽样方法: Distribution::sample ,最后配合rand::Rng的随机数生成器生成随机数。下面示例采用正太分布。

rust 复制代码
use rand_distr::{Distribution, Normal, NormalError};
use rand::thread_rng;

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

生成ASCII密码

随机生成给定长度ASCII字符的字符串,范围为a-z, a-z, 0-9,通过从Alphanumeric中随机抽样产生。

rust 复制代码
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;

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

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

生成用户定义字符密码

随机生成给定长度的ASCII字符字符串,基于用户定义的bytestring,使用gen_range方法:

rust 复制代码
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);
}
相关推荐
крон11 分钟前
【Auto.js例程】华为备忘录导出到其他手机
开发语言·javascript·智能手机
zh_xuan44 分钟前
c++ 单例模式
开发语言·c++·单例模式
老胖闲聊1 小时前
Python Copilot【代码辅助工具】 简介
开发语言·python·copilot
Blossom.1181 小时前
使用Python和Scikit-Learn实现机器学习模型调优
开发语言·人工智能·python·深度学习·目标检测·机器学习·scikit-learn
曹勖之2 小时前
基于ROS2,撰写python脚本,根据给定的舵-桨动力学模型实现动力学更新
开发语言·python·机器人·ros2
豆沙沙包?2 小时前
2025年- H77-Lc185--45.跳跃游戏II(贪心)--Java版
java·开发语言·游戏
军训猫猫头2 小时前
96.如何使用C#实现串口发送? C#例子
开发语言·c#
liuyang-neu3 小时前
java内存模型JMM
java·开发语言
我很好我还能学4 小时前
【面试篇 9】c++生成可执行文件的四个步骤、悬挂指针、define和const区别、c++定义和声明、将引用作为返回值的好处、类的四个缺省函数
开发语言·c++
蓝婷儿5 小时前
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
开发语言·python·学习