Rust生成隨機數(shù)的項目實踐
Rust標準庫中并沒有隨機數(shù)生成器,想要實現(xiàn)此類功能,你需要自行設計(純Rust或FFI到C),或者使用第三方包。
一個常見的解決方案是使用rand包,該項目基于Apache-2.0 和 MIT協(xié)議開源,且擁有完備的文檔:
rust-random/rand: A Rust library for random number generation. (github.com)
0x00 | 在Cargo中導入
在Cargo.toml的[dependencies]下加入以下內(nèi)容即可:
rand = "*"
整個文件看起來會象是這樣:
[package] name = "hello_world" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rand = "*"
0x01 | 生成隨機數(shù)
rand包提供了rand::Rng以生成隨機數(shù),這是一個隨機數(shù)生成器,它的使用是這樣的:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let i: i32 = rng.gen();
let f: f32 = rng.gen();
println!("i={},f={}",i,f);
println!("random u8: {}",rng.gen::<u8>());
println!("random u32: {}",rng.gen::<u32>());
}
0x02 | 給定范圍生成隨機數(shù)
Rng::gen_range函數(shù)能夠在一個左閉又開的區(qū)間內(nèi)生成隨機值:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
println!("random integer: {}",rng.gen_range(0..10)); // 在[0,10)內(nèi)生成隨機整數(shù)
println!("random float: {}",rng.gen_range(0.0..10.0)); // 在[0,10)內(nèi)生成隨機浮點數(shù)
}
Rng::gen_range函數(shù)使用方便,但當在相同范圍內(nèi)連續(xù)生成隨機數(shù)時,其效果可能不盡人意。使用Uniform模塊可以得到符合均勻分布的值,以改善這一問題。如下:
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!("Rool the die: {}",throw);
if throw == 6 {
break;
}
}
}
rand_distr是另一個包,它提供了基于rand包的數(shù)種分布模型,你可以在rand_distr - Rust (docs.rs)中找到相關信息。
以下是生成一個符合正態(tài)分布的隨機數(shù)的實列:
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!("spawn random num {} from N(2,6)",v);
Ok(())
}
0x03 | 給定類型生成隨機值
rand包可以直接生成一個隨機數(shù)元組:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let rand_tuple = rng.gen::<(i32,bool,f64)>();
println!("Random tuple: {:?}",rand_tuple);
}
不過這種方法并不能指定隨機數(shù)的范圍,如果你真的需要限制其范圍,可能需要手動生成每一個值。比如:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let rand_tuple = (
rng.gen_range(0..100),
rng.gen::<bool>(),
rng.gen_range(0.0..1.0)
);
println!("Random tuple: {:?}", rand_tuple);
}
rand包也允許你通過為Standard類實現(xiàn)Distribution特性以將隨機數(shù)生成器集成到你的類中,如下:
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_point: Point = rng.gen();
println!("Random Point: {:?}",rand_point);
}
通過修改sample函數(shù)可以進一步指定范圍和分布模型。
0x04 | 生成隨機字符串
rand包可以生成一個指定長度的隨機ASCII字符串,其樣本為A-Z,a-z,0-9。
一個生成包含30個ASCII字符的隨機字符串的例子如下:
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);
}
當然,也可以從指定的字符集中生成隨機字符串:
use rand::Rng;
fn main() {
const CHARSET: &[u8] = b"123ABC?!";
let mut rng = rand::thread_rng();
let password: String = (0..30)
.map(|_| {
let idx = rng.gen_range(0..CHARSET.len());
CHARSET[idx] as char
})
.collect();
println!("{:?}", password);
}
參考:
生成隨機值 - Rust Cookbook 中文版 (rustwiki.org)
到此這篇關于Rust生成隨機數(shù)的項目實踐的文章就介紹到這了,更多相關Rust生成隨機數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
libbpf和Rust開發(fā)ebpf程序?qū)崙?zhàn)示例
這篇文章主要為大家介紹了libbpf和Rust開發(fā)ebpf程序?qū)崙?zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12

