--- meta-description: Source of the Rust file `src/lib.rs`. meta-generator: rustdoc meta-viewport: width=device-width, initial-scale=1.0 title: lib.rs - source --- [Docs.rs](/) - [fastrand-2.4.1](# "A simple and fast random number generator") - fastrand 2.4.1 - [Permalink](/fastrand/2.4.1/src/fastrand/lib.rs.html "Get a link to this specific version") - [Docs.rs crate page](/crate/fastrand/latest "See fastrand in docs.rs") - [Apache-2.0](https://spdx.org/licenses/Apache-2.0) OR [MIT](https://spdx.org/licenses/MIT) - 07 July 2026 - Links - [Repository](https://github.com/smol-rs/fastrand) - [crates.io](https://crates.io/crates/fastrand "See fastrand in crates.io") - [Source](/crate/fastrand/latest/source/ "Browse source of fastrand-2.4.1") - Owners - [taiki-e](https://crates.io/users/taiki-e) - [github:smol-rs:admins](https://crates.io/teams/github:smol-rs:admins) - Dependencies - - [getrandom ^0.3.4 *dev*](/getrandom/^0.3.4/) - [rand ^0.9 *dev*](/rand/^0.9/) - [wyhash ^0.6 *dev*](/wyhash/^0.6/) - [getrandom ^0.3.4 *normal* *optional*](/getrandom/^0.3.4/) - [getrandom ^0.3.4 *dev*](/getrandom/^0.3.4/) - [wasm-bindgen-test ^0.3 *dev*](/wasm-bindgen-test/^0.3/) - Versions - - [**100%** of the crate is documented](/crate/fastrand/latest) - [Platform](#) - [x86_64-unknown-linux-gnu](/crate/fastrand/latest/target-redirect/src/fastrand/lib.rs.html) - [Feature flags](/crate/fastrand/latest/features "Browse available feature flags of fastrand-2.4.1") - [docs.rs](#) - [About docs.rs](/about) - [Badges](/about/badges) - [Builds](/about/builds) - [Metadata](/about/metadata) - [Shorthand URLs](/about/redirections) - [Download](/about/download) - [Rustdoc JSON](/about/rustdoc-json) - [Build queue](/releases/queue) - [Privacy policy](https://foundation.rust-lang.org/policies/privacy-policy/#docs.rs) - [Rust](#) - [Rust website](https://www.rust-lang.org/) - [The Book](https://doc.rust-lang.org/book/) - [Standard Library API Reference](https://doc.rust-lang.org/std/) - [Rust by Example](https://doc.rust-lang.org/rust-by-example/) - [The Cargo Guide](https://doc.rust-lang.org/cargo/guide/) - [Clippy Documentation](https://doc.rust-lang.org/nightly/clippy) [/-/storage-change-detection.html](/-/storage-change-detection.html) [Skip to main content](#main-content) # fastrand/lib.rs [1](#1)//! A simple and fast random number generator. [2](#2)//! [3](#3)//! The implementation uses [Wyrand](https://github.com/wangyi-fudan/wyhash), a simple and fast [4](#4)//! generator but **not** cryptographically secure. [5](#5)//! [6](#6)//! # Examples [7](#7)//! [8](#8)//! Flip a coin: [9](#9)//! [10](#10)//! ``` [11](#11)//! if fastrand::bool() { [12](#12)//! println!("heads"); [13](#13)//! } else { [14](#14)//! println!("tails"); [15](#15)//! } [16](#16)//! ``` [17](#17)//! [18](#18)//! Generate a random `i32`: [19](#19)//! [20](#20)//! ``` [21](#21)//! let num = fastrand::i32(..); [22](#22)//! ``` [23](#23)//! [24](#24)//! Choose a random element in an array: [25](#25)//! [26](#26)//! ``` [27](#27)//! let v = vec![1, 2, 3, 4, 5]; [28](#28)//! let i = fastrand::usize(..v.len()); [29](#29)//! let elem = v[i]; [30](#30)//! ``` [31](#31)//! [32](#32)//! Sample values from an array with `O(n)` complexity (`n` is the length of array): [33](#33)//! [34](#34)//! ``` [35](#35)//! fastrand::choose_multiple([1, 4, 5], 2); [36](#36)//! fastrand::choose_multiple(0..20, 12); [37](#37)//! ``` [38](#38)//! [39](#39)//! [40](#40)//! Shuffle an array: [41](#41)//! [42](#42)//! ``` [43](#43)//! let mut v = vec![1, 2, 3, 4, 5]; [44](#44)//! fastrand::shuffle(&mut v); [45](#45)//! ``` [46](#46)//! [47](#47)//! Generate a random [`Vec`] or [`String`](alloc::string::String): [48](#48)//! [49](#49)//! ``` [50](#50)//! use std::iter::repeat_with; [51](#51)//! [52](#52)//! let v: Vec = repeat_with(|| fastrand::i32(..)).take(10).collect(); [53](#53)//! let s: String = repeat_with(fastrand::alphanumeric).take(10).collect(); [54](#54)//! ``` [55](#55)//! [56](#56)//! To get reproducible results on every run, initialize the generator with a seed: [57](#57)//! [58](#58)//! ``` [59](#59)//! // Pick an arbitrary number as seed. [60](#60)//! fastrand::seed(7); [61](#61)//! [62](#62)//! // Now this prints the same number on every run: [63](#63)//! println!("{}", fastrand::u32(..)); [64](#64)//! ``` [65](#65)//! [66](#66)//! To be more efficient, create a new [`Rng`] instance instead of using the thread-local [67](#67)//! generator: [68](#68)//! [69](#69)//! ``` [70](#70)//! use std::iter::repeat_with; [71](#71)//! [72](#72)//! let mut rng = fastrand::Rng::new(); [73](#73)//! let mut bytes: Vec = repeat_with(|| rng.u8(..)).take(10_000).collect(); [74](#74)//! ``` [75](#75)//! [76](#76)//! This crate aims to expose a core set of useful randomness primitives. For more niche algorithms, [77](#77)//! consider using the [`fastrand-contrib`] crate alongside this one. [78](#78)//! [79](#79)//! # Features [80](#80)//! [81](#81)//! - `std` (enabled by default): Enables the `std` library. This is required for the global [82](#82)//! generator and global entropy. Without this feature, [`Rng`] can only be instantiated using [83](#83)//! the [`with_seed`](Rng::with_seed) method. [84](#84)//! - `js`: Assumes that WebAssembly targets are being run in a JavaScript environment. See the [85](#85)//! [WebAssembly Notes](#webassembly-notes) section for more information. [86](#86)//! [87](#87)//! # WebAssembly Notes [88](#88)//! [89](#89)//! For non-WASI WASM targets, there is additional subtlety to consider when utilizing the global RNG. [90](#90)//! By default, `std` targets will use entropy sources in the standard library to seed the global RNG. [91](#91)//! However, these sources are not available by default on WASM targets outside of WASI. [92](#92)//! [93](#93)//! If the `js` feature is enabled, this crate will assume that it is running in a JavaScript [94](#94)//! environment. At this point, the [`getrandom`] crate will be used in order to access the available [95](#95)//! entropy sources and seed the global RNG. If the `js` feature is not enabled, the global RNG will [96](#96)//! use a predefined seed. [97](#97)//! [98](#98)//! [`fastrand-contrib`]: https://crates.io/crates/fastrand-contrib [99](#99)//! [`getrandom`]: https://crates.io/crates/getrandom [100](#100) [101](#101)#![no_std] [102](#102)#![cfg_attr(docsrs, feature(doc_cfg))] [103](#103)#![forbid(unsafe_code)] [104](#104)#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)] [105](#105)#![doc( [106](#106) html_favicon_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png" [107](#107))] [108](#108)#![doc( [109](#109) html_logo_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png" [110](#110))] [111](#111) [112](#112)#[cfg(feature = "alloc")] [113](#113)extern crate alloc; [114](#114)#[cfg(feature = "std")] [115](#115)extern crate std; [116](#116) [117](#117)use core::convert::{TryFrom, TryInto}; [118](#118)use core::ops::{Bound, RangeBounds}; [119](#119) [120](#120)#[cfg(feature = "alloc")] [121](#121)use alloc::vec::Vec; [122](#122) [123](#123)#[cfg(feature = "std")] [124](#124)mod global_rng; [125](#125) [126](#126)#[cfg(feature = "std")] [127](#127)pub use global_rng::*; [128](#128) [129](#129)/// A random number generator. [130](#130)#[derive(Debug, PartialEq, Eq)] [131](#131)pub struct Rng(u64); [132](#132) [133](#133)impl Clone for Rng { [134](#134) /// Clones the generator by creating a new generator with the same seed. [135](#135) fn clone(&self) -> Rng { [136](#136) Rng::with_seed(self.0) [137](#137) } [138](#138)} [139](#139) [140](#140)impl Rng { [141](#141) /// Generates a random `u32`. [142](#142) #[inline] [143](#143) fn gen_u32(&mut self) -> u32 { [144](#144) self.gen_u64() as u32 [145](#145) } [146](#146) [147](#147) /// Generates a random `u64`. [148](#148) #[inline] [149](#149) fn gen_u64(&mut self) -> u64 { [150](#150) // Constants for WyRand taken from: https://github.com/wangyi-fudan/wyhash/blob/master/wyhash.h#L151 [151](#151) // Updated for the final v4.2 implementation with improved constants for better entropy output. [152](#152) const WY_CONST_0: u64 = 0x2d35_8dcc_aa6c_78a5; [153](#153) const WY_CONST_1: u64 = 0x8bb8_4b93_962e_acc9; [154](#154) [155](#155) let s = self.0.wrapping_add(WY_CONST_0); [156](#156) self.0 = s; [157](#157) let t = u128::from(s) * u128::from(s ^ WY_CONST_1); [158](#158) (t as u64) ^ (t >> 64) as u64 [159](#159) } [160](#160) [161](#161) /// Generates a random `u128`. [162](#162) #[inline] [163](#163) fn gen_u128(&mut self) -> u128 { [164](#164) (u128::from(self.gen_u64()) << 64) | u128::from(self.gen_u64()) [165](#165) } [166](#166) [167](#167) /// Generates a random `u32` in `0..n`. [168](#168) #[inline] [169](#169) fn gen_mod_u32(&mut self, n: u32) -> u32 { [170](#170) // Adapted from: https://lemire.me/blog/2016/06/30/fast-random-shuffling/ [171](#171) let mut r = self.gen_u32(); [172](#172) let mut hi = mul_high_u32(r, n); [173](#173) let mut lo = r.wrapping_mul(n); [174](#174) if lo < n { [175](#175) let t = n.wrapping_neg() % n; [176](#176) while lo < t { [177](#177) r = self.gen_u32(); [178](#178) hi = mul_high_u32(r, n); [179](#179) lo = r.wrapping_mul(n); [180](#180) } [181](#181) } [182](#182) hi [183](#183) } [184](#184) [185](#185) /// Generates a random `u64` in `0..n`. [186](#186) #[inline] [187](#187) fn gen_mod_u64(&mut self, n: u64) -> u64 { [188](#188) // Adapted from: https://lemire.me/blog/2016/06/30/fast-random-shuffling/ [189](#189) let mut r = self.gen_u64(); [190](#190) let mut hi = mul_high_u64(r, n); [191](#191) let mut lo = r.wrapping_mul(n); [192](#192) if lo < n { [193](#193) let t = n.wrapping_neg() % n; [194](#194) while lo < t { [195](#195) r = self.gen_u64(); [196](#196) hi = mul_high_u64(r, n); [197](#197) lo = r.wrapping_mul(n); [198](#198) } [199](#199) } [200](#200) hi [201](#201) } [202](#202) [203](#203) /// Generates a random `u128` in `0..n`. [204](#204) #[inline] [205](#205) fn gen_mod_u128(&mut self, n: u128) -> u128 { [206](#206) // Adapted from: https://lemire.me/blog/2016/06/30/fast-random-shuffling/ [207](#207) let mut r = self.gen_u128(); [208](#208) let mut hi = mul_high_u128(r, n); [209](#209) let mut lo = r.wrapping_mul(n); [210](#210) if lo < n { [211](#211) let t = n.wrapping_neg() % n; [212](#212) while lo < t { [213](#213) r = self.gen_u128(); [214](#214) hi = mul_high_u128(r, n); [215](#215) lo = r.wrapping_mul(n); [216](#216) } [217](#217) } [218](#218) hi [219](#219) } [220](#220)} [221](#221) [222](#222)/// Computes `(a * b) >> 32`. [223](#223)#[inline] [224](#224)fn mul_high_u32(a: u32, b: u32) -> u32 { [225](#225) (((a as u64) * (b as u64)) >> 32) as u32 [226](#226)} [227](#227) [228](#228)/// Computes `(a * b) >> 64`. [229](#229)#[inline] [230](#230)fn mul_high_u64(a: u64, b: u64) -> u64 { [231](#231) (((a as u128) * (b as u128)) >> 64) as u64 [232](#232)} [233](#233) [234](#234)/// Computes `(a * b) >> 128`. [235](#235)#[inline] [236](#236)fn mul_high_u128(a: u128, b: u128) -> u128 { [237](#237) // Adapted from: https://stackoverflow.com/a/28904636 [238](#238) let a_lo = a as u64 as u128; [239](#239) let a_hi = (a >> 64) as u64 as u128; [240](#240) let b_lo = b as u64 as u128; [241](#241) let b_hi = (b >> 64) as u64 as u128; [242](#242) let carry = (a_lo * b_lo) >> 64; [243](#243) let carry = ((a_hi * b_lo) as u64 as u128 + (a_lo * b_hi) as u64 as u128 + carry) >> 64; [244](#244) a_hi * b_hi + ((a_hi * b_lo) >> 64) + ((a_lo * b_hi) >> 64) + carry [245](#245)} [246](#246) [247](#247)macro_rules! rng_integer { [248](#248) ($t:tt, $unsigned_t:tt, $gen:tt, $mod:tt, $doc:tt) => { [249](#249) #[doc = $doc] [250](#250) /// [251](#251) /// Panics if the range is empty. [252](#252) #[inline] [253](#253) pub fn $t(&mut self, range: impl RangeBounds<$t>) -> $t { [254](#254) let panic_empty_range = || { [255](#255) panic!( [256](#256) "empty range: {:?}..{:?}", [257](#257) range.start_bound(), [258](#258) range.end_bound() [259](#259) ) [260](#260) }; [261](#261) [262](#262) let low = match range.start_bound() { [263](#263) Bound::Unbounded => $t::MIN, [264](#264) Bound::Included(&x) => x, [265](#265) Bound::Excluded(&x) => x.checked_add(1).unwrap_or_else(panic_empty_range), [266](#266) }; [267](#267) [268](#268) let high = match range.end_bound() { [269](#269) Bound::Unbounded => $t::MAX, [270](#270) Bound::Included(&x) => x, [271](#271) Bound::Excluded(&x) => x.checked_sub(1).unwrap_or_else(panic_empty_range), [272](#272) }; [273](#273) [274](#274) if low > high { [275](#275) panic_empty_range(); [276](#276) } [277](#277) [278](#278) if low == $t::MIN && high == $t::MAX { [279](#279) self.$gen() as $t [280](#280) } else { [281](#281) let len = high.wrapping_sub(low).wrapping_add(1); [282](#282) low.wrapping_add(self.$mod(len as $unsigned_t as _) as $t) [283](#283) } [284](#284) } [285](#285) }; [286](#286)} [287](#287) [288](#288)impl Rng { [289](#289) /// Creates a new random number generator with the initial seed. [290](#290) #[inline] [291](#291) #[must_use = "this creates a new instance of `Rng`; if you want to initialize the thread-local generator, use `fastrand::seed()` instead"] [292](#292) pub const fn with_seed(seed: u64) -> Self { [293](#293) Rng(seed) [294](#294) } [295](#295) [296](#296) /// Clones the generator by deterministically deriving a new generator based on the initial [297](#297) /// seed. [298](#298) /// [299](#299) /// This function can be used to create a new generator that is a "spinoff" of the old [300](#300) /// generator. The new generator will not produce the same sequence of values as the [301](#301) /// old generator. [302](#302) /// [303](#303) /// # Example [304](#304) /// [305](#305) /// ``` [306](#306) /// // Seed two generators equally, and clone both of them. [307](#307) /// let mut base1 = fastrand::Rng::with_seed(0x4d595df4d0f33173); [308](#308) /// base1.bool(); // Use the generator once. [309](#309) /// [310](#310) /// let mut base2 = fastrand::Rng::with_seed(0x4d595df4d0f33173); [311](#311) /// base2.bool(); // Use the generator once. [312](#312) /// [313](#313) /// let mut rng1 = base1.fork(); [314](#314) /// let mut rng2 = base2.fork(); [315](#315) /// [316](#316) /// println!("rng1 returns {}", rng1.u32(..)); [317](#317) /// println!("rng2 returns {}", rng2.u32(..)); [318](#318) /// ``` [319](#319) #[inline] [320](#320) #[must_use = "this creates a new instance of `Rng`"] [321](#321) pub fn fork(&mut self) -> Self { [322](#322) Rng::with_seed(self.gen_u64()) [323](#323) } [324](#324) [325](#325) /// Generates a random `char` in ranges a-z and A-Z. [326](#326) #[inline] [327](#327) pub fn alphabetic(&mut self) -> char { [328](#328) const CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; [329](#329) *self.choice(CHARS).unwrap() as char [330](#330) } [331](#331) [332](#332) /// Generates a random `char` in ranges a-z, A-Z and 0-9. [333](#333) #[inline] [334](#334) pub fn alphanumeric(&mut self) -> char { [335](#335) const CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; [336](#336) *self.choice(CHARS).unwrap() as char [337](#337) } [338](#338) [339](#339) /// Generates a random `bool`. [340](#340) #[inline] [341](#341) pub fn bool(&mut self) -> bool { [342](#342) self.u8(..) % 2 == 0 [343](#343) } [344](#344) [345](#345) /// Generates a random digit in the given `base`. [346](#346) /// [347](#347) /// Digits are represented by `char`s in ranges 0-9 and a-z. [348](#348) /// [349](#349) /// Panics if the base is zero or greater than 36. [350](#350) #[inline] [351](#351) pub fn digit(&mut self, base: u32) -> char { [352](#352) if base == 0 { [353](#353) panic!("base cannot be zero"); [354](#354) } [355](#355) if base > 36 { [356](#356) panic!("base cannot be larger than 36"); [357](#357) } [358](#358) let num = self.u8(..base as u8); [359](#359) if num < 10 { [360](#360) (b'0' + num) as char [361](#361) } else { [362](#362) (b'a' + num - 10) as char [363](#363) } [364](#364) } [365](#365) [366](#366) /// Generates a random `f32` in range `0..=1`. [367](#367) #[inline] [368](#368) pub fn f32_inclusive(&mut self) -> f32 { [369](#369) // Generate a number in 0..2^63 then convert to f32 and multiply by 2^(-63). [370](#370) // [371](#371) // Even though we're returning f32, we still generate u64 internally to make [372](#372) // it possible to return nonzero numbers as small as 2^(-63). If we only [373](#373) // generated u32 internally, the smallest nonzero number we could return [374](#374) // would be 2^(-32). [375](#375) // [376](#376) // The integer we generate is in 0..2^63 rather than 0..2^64 to improve speed [377](#377) // on x86-64, which has efficient i64->float conversion (cvtsi2ss) but for [378](#378) // which u64->float conversion must be implemented in software. [379](#379) // [380](#380) // There is still some remaining bias in the int-to-float conversion, because [381](#381) // nonzero numbers <=2^(-64) are never generated, even though they are [382](#382) // expressible in f32. However, at this point the bias in int-to-float conversion [383](#383) // is no larger than the bias in the underlying WyRand generator: since it only [384](#384) // has a 64-bit state, it necessarily already have biases of at least 2^(-64) [385](#385) // probability. [386](#386) // [387](#387) // See e.g. Section 3.1 of Thomas, David B., et al. "Gaussian random number generators, [388](#388) // https://www.doc.ic.ac.uk/~wl/papers/07/csur07dt.pdf, for background. [389](#389) const MUL: f32 = 1.0 / (1u64 << 63) as f32; [390](#390) (self.gen_u64() >> 1) as f32 * MUL [391](#391) } [392](#392) [393](#393) /// Generates a random `f32` in range `0..1`. [394](#394) /// [395](#395) /// Function `f32_inclusive()` is a little simpler and faster, so default [396](#396) /// to that if inclusive range is acceptable. [397](#397) #[inline] [398](#398) pub fn f32(&mut self) -> f32 { [399](#399) loop { [400](#400) let x = self.f32_inclusive(); [401](#401) if x < 1.0 { [402](#402) return x; [403](#403) } [404](#404) } [405](#405) } [406](#406) [407](#407) /// Generates a random `f64` in range `0..=1`. [408](#408) #[inline] [409](#409) pub fn f64_inclusive(&mut self) -> f64 { [410](#410) // See the comment in f32_inclusive() for more details. [411](#411) const MUL: f64 = 1.0 / (1u64 << 63) as f64; [412](#412) (self.gen_u64() >> 1) as f64 * MUL [413](#413) } [414](#414) [415](#415) /// Generates a random `f64` in range `0..1`. [416](#416) /// [417](#417) /// Function `f64_inclusive()` is a little simpler and faster, so default [418](#418) /// to that if inclusive range is acceptable. [419](#419) #[inline] [420](#420) pub fn f64(&mut self) -> f64 { [421](#421) loop { [422](#422) let x = self.f64_inclusive(); [423](#423) if x < 1.0 { [424](#424) return x; [425](#425) } [426](#426) } [427](#427) } [428](#428) [429](#429) /// Collects `amount` values at random from the iterable into a vector. [430](#430) /// [431](#431) /// The length of the returned vector equals `amount` unless the iterable [432](#432) /// contains insufficient elements, in which case it equals the number of [433](#433) /// elements available. [434](#434) /// [435](#435) /// Complexity is `O(n)` where `n` is the length of the iterable. [436](#436) #[cfg(feature = "alloc")] [437](#437) pub fn choose_multiple(&mut self, source: I, amount: usize) -> Vec { [438](#438) // Adapted from: https://docs.rs/rand/latest/rand/seq/trait.IteratorRandom.html#method.choose_multiple [439](#439) let mut reservoir = Vec::with_capacity(amount); [440](#440) let mut iter = source.into_iter(); [441](#441) [442](#442) reservoir.extend(iter.by_ref().take(amount)); [443](#443) [444](#444) // Continue unless the iterator was exhausted [445](#445) // [446](#446) // note: this prevents iterators that "restart" from causing problems. [447](#447) // If the iterator stops once, then so do we. [448](#448) if reservoir.len() == amount { [449](#449) for (i, elem) in iter.enumerate() { [450](#450) let end = i + 1 + amount; [451](#451) let k = self.usize(0..end); [452](#452) if let Some(slot) = reservoir.get_mut(k) { [453](#453) *slot = elem; [454](#454) } [455](#455) } [456](#456) } else { [457](#457) // If less than one third of the `Vec` was used, reallocate [458](#458) // so that the unused space is not wasted. There is a corner [459](#459) // case where `amount` was much less than `self.len()`. [460](#460) if reservoir.capacity() > 3 * reservoir.len() { [461](#461) reservoir.shrink_to_fit(); [462](#462) } [463](#463) } [464](#464) reservoir [465](#465) } [466](#466) [467](#467) rng_integer!( [468](#468) i8, [469](#469) u8, [470](#470) gen_u32, [471](#471) gen_mod_u32, [472](#472) "Generates a random `i8` in the given range." [473](#473) ); [474](#474) [475](#475) rng_integer!( [476](#476) i16, [477](#477) u16, [478](#478) gen_u32, [479](#479) gen_mod_u32, [480](#480) "Generates a random `i16` in the given range." [481](#481) ); [482](#482) [483](#483) rng_integer!( [484](#484) i32, [485](#485) u32, [486](#486) gen_u32, [487](#487) gen_mod_u32, [488](#488) "Generates a random `i32` in the given range." [489](#489) ); [490](#490) [491](#491) rng_integer!( [492](#492) i64, [493](#493) u64, [494](#494) gen_u64, [495](#495) gen_mod_u64, [496](#496) "Generates a random `i64` in the given range." [497](#497) ); [498](#498) [499](#499) rng_integer!( [500](#500) i128, [501](#501) u128, [502](#502) gen_u128, [503](#503) gen_mod_u128, [504](#504) "Generates a random `i128` in the given range." [505](#505) ); [506](#506) [507](#507) #[cfg(target_pointer_width = "16")] [508](#508) rng_integer!( [509](#509) isize, [510](#510) usize, [511](#511) gen_u32, [512](#512) gen_mod_u32, [513](#513) "Generates a random `isize` in the given range." [514](#514) ); [515](#515) #[cfg(target_pointer_width = "32")] [516](#516) rng_integer!( [517](#517) isize, [518](#518) usize, [519](#519) gen_u32, [520](#520) gen_mod_u32, [521](#521) "Generates a random `isize` in the given range." [522](#522) ); [523](#523) #[cfg(target_pointer_width = "64")] [524](#524) rng_integer!( [525](#525) isize, [526](#526) usize, [527](#527) gen_u64, [528](#528) gen_mod_u64, [529](#529) "Generates a random `isize` in the given range." [530](#530) ); [531](#531) [532](#532) /// Generates a random `char` in range a-z. [533](#533) #[inline] [534](#534) pub fn lowercase(&mut self) -> char { [535](#535) const CHARS: &[u8] = b"abcdefghijklmnopqrstuvwxyz"; [536](#536) *self.choice(CHARS).unwrap() as char [537](#537) } [538](#538) [539](#539) /// Initializes this generator with the given seed. [540](#540) #[inline] [541](#541) pub fn seed(&mut self, seed: u64) { [542](#542) self.0 = seed; [543](#543) } [544](#544) [545](#545) /// Gives back **current** seed that is being held by this generator. [546](#546) #[inline] [547](#547) pub fn get_seed(&self) -> u64 { [548](#548) self.0 [549](#549) } [550](#550) [551](#551) /// Choose an item from an iterator at random. [552](#552) /// [553](#553) /// This function may have an unexpected result if the `len()` property of the [554](#554) /// iterator does not match the actual number of items in the iterator. If [555](#555) /// the iterator is empty, this returns `None`. [556](#556) #[inline] [557](#557) pub fn choice(&mut self, iter: I) -> Option [558](#558) where [559](#559) I: IntoIterator, [560](#560) I::IntoIter: ExactSizeIterator, [561](#561) { [562](#562) let mut iter = iter.into_iter(); [563](#563) [564](#564) // Get the item at a random index. [565](#565) let len = iter.len(); [566](#566) if len == 0 { [567](#567) return None; [568](#568) } [569](#569) let index = self.usize(0..len); [570](#570) [571](#571) iter.nth(index) [572](#572) } [573](#573) [574](#574) /// Shuffles a slice randomly. [575](#575) #[inline] [576](#576) pub fn shuffle(&mut self, slice: &mut [T]) { [577](#577) for i in 1..slice.len() { [578](#578) slice.swap(i, self.usize(..=i)); [579](#579) } [580](#580) } [581](#581) [582](#582) /// Fill a byte slice with random data. [583](#583) #[inline] [584](#584) pub fn fill(&mut self, slice: &mut [u8]) { [585](#585) // We fill the slice by chunks of 8 bytes, or one block of [586](#586) // WyRand output per new state. [587](#587) let mut chunks = slice.chunks_exact_mut(core::mem::size_of::()); [588](#588) for chunk in chunks.by_ref() { [589](#589) let n = self.gen_u64().to_ne_bytes(); [590](#590) // Safe because the chunks are always 8 bytes exactly. [591](#591) chunk.copy_from_slice(&n); [592](#592) } [593](#593) [594](#594) let remainder = chunks.into_remainder(); [595](#595) [596](#596) // Any remainder will always be less than 8 bytes. [597](#597) if !remainder.is_empty() { [598](#598) // Generate one last block of 8 bytes of entropy [599](#599) let n = self.gen_u64().to_ne_bytes(); [600](#600) [601](#601) // Use the remaining length to copy from block [602](#602) remainder.copy_from_slice(&n[..remainder.len()]); [603](#603) } [604](#604) } [605](#605) [606](#606) rng_integer!( [607](#607) u8, [608](#608) u8, [609](#609) gen_u32, [610](#610) gen_mod_u32, [611](#611) "Generates a random `u8` in the given range." [612](#612) ); [613](#613) [614](#614) rng_integer!( [615](#615) u16, [616](#616) u16, [617](#617) gen_u32, [618](#618) gen_mod_u32, [619](#619) "Generates a random `u16` in the given range." [620](#620) ); [621](#621) [622](#622) rng_integer!( [623](#623) u32, [624](#624) u32, [625](#625) gen_u32, [626](#626) gen_mod_u32, [627](#627) "Generates a random `u32` in the given range." [628](#628) ); [629](#629) [630](#630) rng_integer!( [631](#631) u64, [632](#632) u64, [633](#633) gen_u64, [634](#634) gen_mod_u64, [635](#635) "Generates a random `u64` in the given range." [636](#636) ); [637](#637) [638](#638) rng_integer!( [639](#639) u128, [640](#640) u128, [641](#641) gen_u128, [642](#642) gen_mod_u128, [643](#643) "Generates a random `u128` in the given range." [644](#644) ); [645](#645) [646](#646) #[cfg(target_pointer_width = "16")] [647](#647) rng_integer!( [648](#648) usize, [649](#649) usize, [650](#650) gen_u32, [651](#651) gen_mod_u32, [652](#652) "Generates a random `usize` in the given range." [653](#653) ); [654](#654) #[cfg(target_pointer_width = "32")] [655](#655) rng_integer!( [656](#656) usize, [657](#657) usize, [658](#658) gen_u32, [659](#659) gen_mod_u32, [660](#660) "Generates a random `usize` in the given range." [661](#661) ); [662](#662) #[cfg(target_pointer_width = "64")] [663](#663) rng_integer!( [664](#664) usize, [665](#665) usize, [666](#666) gen_u64, [667](#667) gen_mod_u64, [668](#668) "Generates a random `usize` in the given range." [669](#669) ); [670](#670) [671](#671) /// Generates a random `char` in range A-Z. [672](#672) #[inline] [673](#673) pub fn uppercase(&mut self) -> char { [674](#674) const CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; [675](#675) *self.choice(CHARS).unwrap() as char [676](#676) } [677](#677) [678](#678) /// Generates a random `char` in the given range. [679](#679) /// [680](#680) /// Panics if the range is empty. [681](#681) #[inline] [682](#682) pub fn char(&mut self, range: impl RangeBounds) -> char { [683](#683) let panic_empty_range = || { [684](#684) panic!( [685](#685) "empty range: {:?}..{:?}", [686](#686) range.start_bound(), [687](#687) range.end_bound() [688](#688) ) [689](#689) }; [690](#690) [691](#691) let surrogate_start = 0xd800u32; [692](#692) let surrogate_len = 0x800u32; [693](#693) [694](#694) let low = match range.start_bound() { [695](#695) Bound::Unbounded => 0u8 as char, [696](#696) Bound::Included(&x) => x, [697](#697) Bound::Excluded(&x) => { [698](#698) let scalar = if x as u32 == surrogate_start - 1 { [699](#699) surrogate_start + surrogate_len [700](#700) } else { [701](#701) x as u32 + 1 [702](#702) }; [703](#703) char::try_from(scalar).unwrap_or_else(|_| panic_empty_range()) [704](#704) } [705](#705) }; [706](#706) [707](#707) let high = match range.end_bound() { [708](#708) Bound::Unbounded => core::char::MAX, [709](#709) Bound::Included(&x) => x, [710](#710) Bound::Excluded(&x) => { [711](#711) let scalar = if x as u32 == surrogate_start + surrogate_len { [712](#712) surrogate_start - 1 [713](#713) } else { [714](#714) (x as u32).wrapping_sub(1) [715](#715) }; [716](#716) char::try_from(scalar).unwrap_or_else(|_| panic_empty_range()) [717](#717) } [718](#718) }; [719](#719) [720](#720) if low > high { [721](#721) panic_empty_range(); [722](#722) } [723](#723) [724](#724) let gap = if (low as u32) < surrogate_start && (high as u32) >= surrogate_start { [725](#725) surrogate_len [726](#726) } else { [727](#727) 0 [728](#728) }; [729](#729) let range = high as u32 - low as u32 - gap; [730](#730) let mut val = self.u32(0..=range) + low as u32; [731](#731) if val >= surrogate_start { [732](#732) val += gap; [733](#733) } [734](#734) val.try_into().unwrap() [735](#735) } [736](#736)}