2 个版本
0.1.1 | 2022年11月4日 |
---|---|
0.1.0 | 2020年8月4日 |
#1341 在 算法
72 每月下载量
用于 2 crates
89KB
1.5K SLoC
µrandom
生成和消耗随机数。
此 crate 提供了生成随机数、将它们转换为有用的类型和分布以及一些随机相关算法的实用工具。
快速入门
为了快速入门,获取随机值的最高级和最简单的方法是使用 urandom::new().next()
. Random
结构体为所有 Rngs 提供了有用的 API,而 distributions
模块在 Rngs 上提供了进一步的功能。
let mut rng = urandom::new();
// Generates a random boolean
if rng.coin_flip() {
// Try printing a random unicode code point (probably a bad idea)!
println!("char: {}", rng.next::<char>());
}
// Generates a float between 13.0 and 42.0
let y: f64 = rng.range(13.0..42.0);
// Shuffles the list of numbers
let mut numbers: Vec<i32> = (1..100).collect();
rng.shuffle(&mut numbers);
这个库受到了半官方的 rand
crate 和尝试提供更好体验的启发。
常见问题解答
Q: 为什么还需要另一个随机数生成器 crate?
A: 因为我认为我可以比标准 rand crate 的设计做得更好。我的随机 crate 更简单,更容易使用,并且在运行时更快。
Q: 实现了哪些随机数生成器?
A: Xoshiro256
作为 PRNG 由 Sebastiano Vigna 和 David Blackman 实现(当从 u64
中初始化时由 SplitMix64
支持)。ChaCha20
作为 CSPRNG 由 Daniel J. Bernstein 实现。getrandom
作为系统熵的来源。
Q: 为什么随机浮点数生成在半开区间 [1.0, 2.0)
而不是 [0.0, 1.0)
?
答:因为这更简单、更快,并且避免了困难(设计和实现)问题。天真地减去 1.0
会在浮点数的尾数低比特位留下偏差(见 examples/float_bias.rs
)。Float01
分布生成一个不带有偏差的随机浮点数,在开区间 (0.0, 1.0)
。
问:这基本上是将 rand
粘贴过来,但功能更少
答:这根本不是问题。与分布相关的结构和特性行设计得相当不错,不需要太多更改。我专注于伪随机数生成器本身,Rng
特性和 Random
接口以及构造函数。
问:那么,rand
什么地方出问题了?
答:有几件事让我印象深刻。我不喜欢线程局部变量,它们与全局状态有相同的问题,只是它们是线程安全的。但全局变量仍然很糟糕。
rand
仓库将它的 thread_rng
置于首位,因为它是最容易生成随机性的方法(通过显式使用或 random
方法)。我直接从系统的 getrandom 中为新的伪随机数生成器播种。
rand
仓库需要导入很多特性才能使用其功能。当然,这通过 prelude
模块得到了一定程度的缓解,但我不喜欢。Rust IDE 体验还不够好,无法使这个过程顺畅(例如,自动导入缺失的特性)。我将功能作为 Random
结构体的固有方法来实现,无需导入,并提供流畅的 IDE 体验。
rand
仓库试图过度抽象,例如,CryptoRng
特性和相关功能。这些有助于 实现 所需的抽象,以便将其用于伪随机数生成器。
问:这个仓库在没有 getrandom 用于播种的情况下如何工作?
答:当选择不使用 getrandom
仓库时,其功能被推迟到名为 getentropy_raw
的函数中,具有 C 连接。只需像在 C 中定义符号一样定义此符号,它就会被链接起来,作为安全的熵源。
问:它在 32 位系统上表现如何?
答:我针对具有快速全 64 位整数乘法的 64 位架构优化了此仓库。
许可
在 MIT 许可证 下许可,见 license.txt。
贡献
除非你明确说明,否则你提交的任何旨在包含在作品中的贡献都应按上述方式许可,不附加任何额外条款或条件。
依赖关系
~120–295KB