🚴♀️
randを用いたRustの簡単な乱数メモ
スクラップにメモしていたシリーズです。randクレートで乱数生成する方法を調べた結果のメモです。[rand "0.8.5"]
前提
Cargo.toml
[dependencies]
rand = "0.8.5"
サンプルコード
use rand::prelude::*;
fn main() {
// random<T>() is shortcut of thread_rng().gen()
if random() { // generates a boolean
let _ = random::<f64>(); // generates a float between 0 and 1
}
let mut rng1: ThreadRng = thread_rng();
let _foo: u32 = rng1.gen_range(4_u32..9);
let _bar: i32 = rng1.gen_range(-5..=5);
let _baz: f64 = rng1.gen_range(1.0..2.0);
let _qux: bool = rng1.gen_ratio(2_u32, 3); // probability of true is about 67%
// generates with seed
let seed: [u8; 32] = [0; 32];
let mut rng2: StdRng = StdRng::from_seed(seed);
let _ = rng2.gen::<f64>();
// random sort
let mut vec: Vec<i32> = (1..10).collect();
vec.shuffle(&mut rng1);
println!("{:?}", vec);
}
メモ
- 4種類の生成器がある
-
OsRng
,ThreadRng
,StdRng
,SmallRng
-
-
StdRng
とSmallRng
は将来のリリースでアルゴリズムが変わる可能性がある -
rand_distr
クレートを使用すると標準偏差など乱数を偏らせることができる
おまけ
- 以下の場合に使用可能な代替方法
- セキュアさが明確に不要
- 人間にとって乱数のように感じるだけでいい
- クレートを追加するほどでもないショボい用途
fn main() {
if get_random_like_bool() {
println!("{}", get_random_like_digit());
}
}
fn get_random_like_bool() -> bool { get_time_uint() % 2 > 0 }
fn get_random_like_digit() -> u128 { get_time_uint() % 10 }
fn get_time_uint() -> u128 {
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_nanos()
}
Discussion