pkce_std/generate.rs
1//! Generating random bytes and strings.
2//!
3//! This module provides two functions for generating random bytes and strings:
4//! [`bytes`] and [`string`] accepting the desired length as [`Count`] and [`Length`] respectively.
5//!
6//! Because of the imposed length restrictions, the functions are safe to use
7//! in the context of this crate. See [`count`] and [`length`] for more information.
8//!
9//! [`count`]: crate::count
10//! [`length`]: crate::length
11
12#[cfg(feature = "unsafe-assert")]
13use std::hint::assert_unchecked;
14
15use rand::{Rng, RngCore, distr::Uniform, rng};
16
17use crate::{
18 check::chars::{CHARS, LENGTH},
19 count::Count,
20 length::Length,
21};
22
23/// Generates `count` random bytes.
24pub fn bytes(count: Count) -> Vec<u8> {
25 let mut data = vec![0; count.get()];
26
27 rng().fill_bytes(&mut data);
28
29 data
30}
31
32/// Generates random strings of `length` characters from the [`CHARS`] set.
33///
34/// # Panics
35///
36/// This function will not panic, as detailed below.
37///
38/// ## Distribution
39///
40/// The uniform distribution is created with constantly checked [`LENGTH`] being non-zero.
41///
42/// ## Bounds
43///
44/// [`CHARS`] is the array containing exactly [`LENGTH`] characters. Since the uniform range
45/// is exclusive, the sampled index will always be in the bounds of the array.
46///
47/// ## Feature
48///
49/// Moreover, the `unsafe-assert` feature can be enabled to `assume` the bounds are correct.
50pub fn string(length: Length) -> String {
51 let distribution = Uniform::new(0, LENGTH).unwrap();
52
53 rng()
54 .sample_iter(distribution)
55 .take(length.get())
56 .map(|index| {
57 #[cfg(feature = "unsafe-assert")]
58 unsafe {
59 assert_unchecked(index < LENGTH);
60 }
61
62 CHARS[index]
63 })
64 .collect()
65}