#![no_std]
#![warn(clippy::all, clippy::pedantic, clippy::cargo)]
#![warn(missing_docs)]
#![allow(clippy::module_name_repetitions)] #![allow(clippy::similar_names)] #![allow(unreachable_patterns)] #![allow(clippy::too_many_lines)] #![allow(clippy::must_use_candidate)] #![allow(clippy::missing_errors_doc)] #![allow(clippy::missing_panics_doc)] #![allow(clippy::missing_docs_in_private_items)] #![allow(clippy::if_same_then_else)]
extern crate alloc;
use alloc::string::String;
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
use alloc::sync::Arc;
#[cfg(feature = "rand")]
use alloc::vec;
use alloc::vec::Vec;
#[cfg(feature = "adjectives")]
mod adjectives;
#[cfg(feature = "first_names")]
mod first_names;
#[cfg(feature = "last_names")]
mod last_names;
#[cfg(feature = "names")]
mod names;
#[cfg(feature = "nouns")]
mod nouns;
#[cfg(feature = "words")]
mod words;
#[cfg(any(feature = "core", feature = "send_only"))]
pub use rand::rngs::StdRng;
#[cfg(all(feature = "core", not(feature = "send_only")))]
pub use rand::rngs::ThreadRng;
#[cfg(feature = "core")]
pub use rand::rngs::OsRng;
#[cfg(feature = "custom")]
pub use getrandom::register_custom_getrandom;
#[cfg(feature = "rand")]
pub use rand::{CryptoRng, Error, Rng, RngCore, SeedableRng};
#[cfg(feature = "rand")]
#[inline]
fn filter_printable_char(mut value: u8) -> u8 {
if (33..=37).contains(&value) {
value += 20;
} else if (38..=47).contains(&value) {
value += 10;
} else if (58..=64).contains(&value) {
value += 10;
} else if (91..=96).contains(&value) {
value += 10;
}
value
}
#[cfg(feature = "rand")]
#[inline]
fn filter_alphanumeric_char(mut value: u8) -> u8 {
if (58..=64).contains(&value) {
value += 10;
} else if (91..=96).contains(&value) {
value += 10;
}
value
}
#[cfg(any(feature = "first_names", feature = "last_names"))]
#[allow(dead_code)]
fn to_title_case(s: &str) -> String {
let mut chars = s.chars();
match chars.next() {
None => String::new(),
Some(first) => {
let mut result = String::with_capacity(s.len());
for c in first.to_uppercase() {
result.push(c);
}
for c in chars {
for lc in c.to_lowercase() {
result.push(lc);
}
}
result
}
}
}
#[cfg(feature = "custom")]
#[derive(Clone)]
pub struct CustomRng {
rng: Arc<spin::mutex::Mutex<dyn RngCore>>,
}
#[cfg(feature = "custom")]
impl CustomRng {
pub fn new(rng: impl RngCore + 'static) -> Self {
Self {
rng: Arc::new(spin::mutex::Mutex::new(rng)),
}
}
}
#[cfg(feature = "custom")]
impl RngCore for CustomRng {
fn next_u32(&mut self) -> u32 {
let mut rl = self.rng.lock();
rl.next_u32()
}
fn next_u64(&mut self) -> u64 {
let mut rl = self.rng.lock();
rl.next_u64()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
let mut rl = self.rng.lock();
rl.fill_bytes(dest);
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
let mut rl = self.rng.lock();
rl.try_fill_bytes(dest)
}
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
pub trait RngCrypto: RngCore + CryptoRng {}
#[derive(Clone)]
#[cfg(feature = "custom")]
pub struct CustomCryptoRng {
rng: Arc<spin::mutex::Mutex<dyn RngCrypto>>,
}
#[cfg(feature = "custom")]
impl CustomCryptoRng {
pub fn new(rng: impl RngCrypto + 'static) -> Self {
Self {
rng: Arc::new(spin::mutex::Mutex::new(rng)),
}
}
}
#[cfg(feature = "custom")]
impl RngCrypto for CustomCryptoRng {}
#[cfg(feature = "custom")]
impl CryptoRng for CustomCryptoRng {}
#[cfg(feature = "custom")]
impl RngCore for CustomCryptoRng {
fn next_u32(&mut self) -> u32 {
let mut rl = self.rng.lock();
rl.next_u32()
}
fn next_u64(&mut self) -> u64 {
let mut rl = self.rng.lock();
rl.next_u64()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
let mut rl = self.rng.lock();
rl.fill_bytes(dest);
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
let mut rl = self.rng.lock();
rl.try_fill_bytes(dest)
}
}
#[cfg(feature = "rand")]
#[allow(clippy::large_enum_variant)]
#[derive(Clone)]
pub enum RNG {
#[cfg(any(feature = "core", feature = "send_only"))]
Std(StdRng),
#[cfg(all(feature = "core", not(feature = "send_only")))]
Thread(ThreadRng),
#[cfg(feature = "core")]
OS(OsRng),
#[cfg(feature = "custom")]
Custom(CustomRng),
#[cfg(feature = "custom")]
CustomRaw(Arc<spin::mutex::Mutex<dyn RngCore>>),
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
CustomRawSend(Arc<spin::mutex::Mutex<dyn RngCore + Send>>),
#[cfg(feature = "custom")]
CustomCrypto(CustomCryptoRng),
#[cfg(feature = "custom")]
CustomCryptoRaw(Arc<spin::mutex::Mutex<dyn RngCrypto>>),
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
CustomCryptoRawSend(Arc<spin::mutex::Mutex<dyn RngCrypto + Send>>),
}
#[cfg(feature = "rand")]
impl RngCore for RNG {
fn next_u32(&mut self) -> u32 {
match self {
#[cfg(any(feature = "core", feature = "send_only"))]
RNG::Std(r) => r.next_u32(),
#[cfg(all(feature = "core", not(feature = "send_only")))]
RNG::Thread(r) => r.next_u32(),
#[cfg(feature = "core")]
RNG::OS(r) => r.next_u32(),
#[cfg(feature = "custom")]
RNG::Custom(r) => r.next_u32(),
#[cfg(feature = "custom")]
RNG::CustomRaw(r) => {
let mut rl = r.lock();
rl.next_u32()
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
RNG::CustomRawSend(r) => {
let mut rl = r.lock();
rl.next_u32()
}
#[cfg(feature = "custom")]
RNG::CustomCrypto(r) => r.next_u32(),
#[cfg(feature = "custom")]
RNG::CustomCryptoRaw(r) => {
let mut rl = r.lock();
rl.next_u32()
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
RNG::CustomCryptoRawSend(r) => {
let mut rl = r.lock();
rl.next_u32()
}
_ => panic!("No known random generator"),
}
}
fn next_u64(&mut self) -> u64 {
match self {
#[cfg(any(feature = "core", feature = "send_only"))]
RNG::Std(r) => r.next_u64(),
#[cfg(all(feature = "core", not(feature = "send_only")))]
RNG::Thread(r) => r.next_u64(),
#[cfg(feature = "core")]
RNG::OS(r) => r.next_u64(),
#[cfg(feature = "custom")]
RNG::Custom(r) => r.next_u64(),
#[cfg(feature = "custom")]
RNG::CustomRaw(r) => {
let mut rl = r.lock();
rl.next_u64()
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
RNG::CustomRawSend(r) => {
let mut rl = r.lock();
rl.next_u64()
}
#[cfg(feature = "custom")]
RNG::CustomCrypto(r) => r.next_u64(),
#[cfg(feature = "custom")]
RNG::CustomCryptoRaw(r) => {
let mut rl = r.lock();
rl.next_u64()
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
RNG::CustomCryptoRawSend(r) => {
let mut rl = r.lock();
rl.next_u64()
}
_ => panic!("No known random generator"),
}
}
#[allow(unused_variables)]
fn fill_bytes(&mut self, dest: &mut [u8]) {
match self {
#[cfg(any(feature = "core", feature = "send_only"))]
RNG::Std(r) => r.fill_bytes(dest),
#[cfg(all(feature = "core", not(feature = "send_only")))]
RNG::Thread(r) => r.fill_bytes(dest),
#[cfg(feature = "core")]
RNG::OS(r) => r.fill_bytes(dest),
#[cfg(feature = "custom")]
RNG::Custom(r) => r.fill_bytes(dest),
#[cfg(feature = "custom")]
RNG::CustomRaw(r) => {
let mut rl = r.lock();
rl.fill_bytes(dest);
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
RNG::CustomRawSend(r) => {
let mut rl = r.lock();
rl.fill_bytes(dest);
}
#[cfg(feature = "custom")]
RNG::CustomCrypto(r) => r.fill_bytes(dest),
#[cfg(feature = "custom")]
RNG::CustomCryptoRaw(r) => {
let mut rl = r.lock();
rl.fill_bytes(dest);
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
RNG::CustomCryptoRawSend(r) => {
let mut rl = r.lock();
rl.fill_bytes(dest);
}
_ => panic!("No known random generator"),
}
}
#[allow(unused_variables)]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
match self {
#[cfg(any(feature = "core", feature = "send_only"))]
RNG::Std(r) => r.try_fill_bytes(dest),
#[cfg(all(feature = "core", not(feature = "send_only")))]
RNG::Thread(r) => r.try_fill_bytes(dest),
#[cfg(feature = "core")]
RNG::OS(r) => r.try_fill_bytes(dest),
#[cfg(feature = "custom")]
RNG::Custom(r) => r.try_fill_bytes(dest),
#[cfg(feature = "custom")]
RNG::CustomRaw(r) => {
let mut rl = r.lock();
rl.try_fill_bytes(dest)
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
RNG::CustomRawSend(r) => {
let mut rl = r.lock();
rl.try_fill_bytes(dest)
}
#[cfg(feature = "custom")]
RNG::CustomCrypto(r) => r.try_fill_bytes(dest),
#[cfg(feature = "custom")]
RNG::CustomCryptoRaw(r) => {
let mut rl = r.lock();
rl.try_fill_bytes(dest)
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
RNG::CustomCryptoRawSend(r) => {
let mut rl = r.lock();
rl.try_fill_bytes(dest)
}
_ => panic!("No known random generator"),
}
}
}
#[cfg(feature = "rand")]
#[allow(clippy::large_enum_variant)]
#[derive(Clone)]
pub enum CryptoRNG {
#[cfg(any(feature = "core", feature = "send_only"))]
Std(StdRng),
#[cfg(all(feature = "core", not(feature = "send_only")))]
Thread(ThreadRng),
#[cfg(feature = "core")]
OS(OsRng),
#[cfg(feature = "custom")]
CustomCrypto(CustomCryptoRng),
#[cfg(feature = "custom")]
CustomCryptoRaw(Arc<spin::mutex::Mutex<dyn RngCrypto>>),
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
CustomCryptoRawSend(Arc<spin::mutex::Mutex<dyn RngCrypto + Send>>),
}
#[cfg(feature = "rand")]
impl CryptoRng for CryptoRNG {}
#[cfg(feature = "rand")]
impl RngCore for CryptoRNG {
fn next_u32(&mut self) -> u32 {
match self {
#[cfg(any(feature = "core", feature = "send_only"))]
CryptoRNG::Std(r) => r.next_u32(),
#[cfg(all(feature = "core", not(feature = "send_only")))]
CryptoRNG::Thread(r) => r.next_u32(),
#[cfg(feature = "core")]
CryptoRNG::OS(r) => r.next_u32(),
#[cfg(feature = "custom")]
CryptoRNG::CustomCrypto(r) => r.next_u32(),
#[cfg(feature = "custom")]
CryptoRNG::CustomCryptoRaw(r) => {
let mut rl = r.lock();
rl.next_u32()
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
CryptoRNG::CustomCryptoRawSend(r) => {
let mut rl = r.lock();
rl.next_u32()
}
_ => panic!("No known random generator"),
}
}
fn next_u64(&mut self) -> u64 {
match self {
#[cfg(any(feature = "core", feature = "send_only"))]
CryptoRNG::Std(r) => r.next_u64(),
#[cfg(all(feature = "core", not(feature = "send_only")))]
CryptoRNG::Thread(r) => r.next_u64(),
#[cfg(feature = "core")]
CryptoRNG::OS(r) => r.next_u64(),
#[cfg(feature = "custom")]
CryptoRNG::CustomCrypto(r) => r.next_u64(),
#[cfg(feature = "custom")]
CryptoRNG::CustomCryptoRaw(r) => {
let mut rl = r.lock();
rl.next_u64()
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
CryptoRNG::CustomCryptoRawSend(r) => {
let mut rl = r.lock();
rl.next_u64()
}
_ => panic!("No known random generator"),
}
}
#[allow(unused_variables)]
fn fill_bytes(&mut self, dest: &mut [u8]) {
match self {
#[cfg(any(feature = "core", feature = "send_only"))]
CryptoRNG::Std(r) => r.fill_bytes(dest),
#[cfg(all(feature = "core", not(feature = "send_only")))]
CryptoRNG::Thread(r) => r.fill_bytes(dest),
#[cfg(feature = "core")]
CryptoRNG::OS(r) => r.fill_bytes(dest),
#[cfg(feature = "custom")]
CryptoRNG::CustomCrypto(r) => r.fill_bytes(dest),
#[cfg(feature = "custom")]
CryptoRNG::CustomCryptoRaw(r) => {
let mut rl = r.lock();
rl.fill_bytes(dest);
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
CryptoRNG::CustomCryptoRawSend(r) => {
let mut rl = r.lock();
rl.fill_bytes(dest);
}
_ => panic!("No known random generator"),
}
}
#[allow(unused_variables)]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
match self {
#[cfg(any(feature = "core", feature = "send_only"))]
CryptoRNG::Std(r) => r.try_fill_bytes(dest),
#[cfg(all(feature = "core", not(feature = "send_only")))]
CryptoRNG::Thread(r) => r.try_fill_bytes(dest),
#[cfg(feature = "core")]
CryptoRNG::OS(r) => r.try_fill_bytes(dest),
#[cfg(feature = "custom")]
CryptoRNG::CustomCrypto(r) => r.try_fill_bytes(dest),
#[cfg(feature = "custom")]
CryptoRNG::CustomCryptoRaw(r) => {
let mut rl = r.lock();
rl.try_fill_bytes(dest)
}
#[cfg(any(feature = "custom", feature = "custom_send_only"))]
CryptoRNG::CustomCryptoRawSend(r) => {
let mut rl = r.lock();
rl.try_fill_bytes(dest)
}
_ => panic!("No known random generator"),
}
}
}
#[cfg(feature = "rand")]
#[derive(Clone)]
pub struct RandomGenerator {
generator: RNG,
}
#[cfg(any(feature = "constrained", feature = "core", feature = "send_only"))]
impl RandomGenerator {
pub fn new(gen: Option<RNG>) -> Self {
let generator = {
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(g) => g,
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
gen.unwrap_or_else(|| RNG::Std(StdRng::from_entropy()))
}
};
Self { generator }
}
pub fn generate_simple_key_one_time(len: usize) -> Vec<u8> {
RandomGenerator::generate_key_one_time(len, &mut None::<RNG>)
}
pub fn generate_key_one_time(len: usize, gen: &mut Option<impl RngCore>) -> Vec<u8> {
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
let mut key = Vec::with_capacity(len);
for _ in 0..len {
key.push(rng.gen());
}
key
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
let mut key = Vec::with_capacity(len);
for _ in 0..len {
key.push(rng.gen());
}
key
} else {
let mut rng = StdRng::from_entropy();
let mut key = Vec::with_capacity(len);
for _ in 0..len {
key.push(rng.gen());
}
key
}
}
}
pub fn get_simple_random_bytes_one_time(len: usize) -> Vec<u8> {
RandomGenerator::get_random_bytes_one_time(len, &mut None::<RNG>)
}
pub fn get_random_bytes_one_time(len: usize, gen: &mut Option<impl RngCore>) -> Vec<u8> {
let mut bytes = vec![0u8; len];
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
rng.fill_bytes(&mut bytes);
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
rng.fill_bytes(&mut bytes);
} else {
let mut rng = StdRng::from_entropy();
rng.fill_bytes(&mut bytes);
}
}
bytes
}
pub fn get_simple_random_usize_one_time(min: usize, max: usize) -> usize {
RandomGenerator::get_random_usize_one_time(min, max, &mut None::<RNG>)
}
pub fn get_random_usize_one_time(
min: usize,
max: usize,
gen: &mut Option<impl RngCore>,
) -> usize {
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => rng.gen_range(min..=max),
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
rng.gen_range(min..=max)
} else {
let mut rng = StdRng::from_entropy();
rng.gen_range(min..=max)
}
}
}
pub fn get_simple_random_string_one_time(len: usize) -> String {
RandomGenerator::get_random_string_one_time(len, &mut None::<RNG>)
}
pub fn get_random_string_one_time(len: usize, gen: &mut Option<impl RngCore>) -> String {
let mut str = String::with_capacity(len);
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
for _ in 0..len {
let value: u8 = rng.gen_range(33..=122);
let filtered = filter_printable_char(value);
str.push(char::from(filtered));
}
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
for _ in 0..len {
let value: u8 = rng.gen_range(33..=122);
let filtered = filter_printable_char(value);
str.push(char::from(filtered));
}
} else {
let mut rng = StdRng::from_entropy();
for _ in 0..len {
let value: u8 = rng.gen_range(33..=122);
let filtered = filter_printable_char(value);
str.push(char::from(filtered));
}
}
}
str
}
pub fn get_simple_random_from_characters_one_time(len: usize, characters: &str) -> String {
RandomGenerator::get_random_from_characters_one_time(len, characters, &mut None::<RNG>)
}
pub fn get_random_from_characters_one_time(
len: usize,
characters: &str,
gen: &mut Option<impl RngCore>,
) -> String {
let mut str = String::with_capacity(len);
let char_vec: Vec<char> = characters.chars().collect();
let char_count = char_vec.len();
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
for _ in 0..len {
let ch = char_vec[rng.gen_range(0..char_count)];
str.push(ch);
}
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
for _ in 0..len {
let ch = char_vec[rng.gen_range(0..char_count)];
str.push(ch);
}
} else {
let mut rng = StdRng::from_entropy();
for _ in 0..len {
let ch = char_vec[rng.gen_range(0..char_count)];
str.push(ch);
}
}
}
str
}
pub fn get_simple_random_alphanumeric_one_time(len: usize) -> String {
RandomGenerator::get_random_alphanumeric_one_time(len, &mut None::<RNG>)
}
pub fn get_random_alphanumeric_one_time(len: usize, gen: &mut Option<impl RngCore>) -> String {
let mut str = String::with_capacity(len);
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
for _ in 0..len {
let value: u8 = rng.gen_range(48..=122);
let filtered = filter_alphanumeric_char(value);
str.push(char::from(filtered));
}
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
for _ in 0..len {
let value: u8 = rng.gen_range(48..=122);
let filtered = filter_alphanumeric_char(value);
str.push(char::from(filtered));
}
} else {
let mut rng = StdRng::from_entropy();
for _ in 0..len {
let value: u8 = rng.gen_range(48..=122);
let filtered = filter_alphanumeric_char(value);
str.push(char::from(filtered));
}
}
}
str
}
pub fn get_simple_random_password_one_time(len: usize) -> String {
RandomGenerator::get_random_password_one_time(len, &mut None::<RNG>)
}
pub fn get_random_password_one_time(len: usize, gen: &mut Option<impl RngCore>) -> String {
let mut str = String::with_capacity(len);
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
for _ in 0..len {
let value: u8 = rng.gen_range(33..=122);
str.push(char::from(value));
}
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
for _ in 0..len {
let value: u8 = rng.gen_range(33..=122);
str.push(char::from(value));
}
} else {
let mut rng = StdRng::from_entropy();
for _ in 0..len {
let value: u8 = rng.gen_range(33..=122);
str.push(char::from(value));
}
}
}
str
}
#[cfg(feature = "names")]
pub fn get_simple_random_email_one_time(
num_names: Option<usize>,
num_numbers: Option<usize>,
separator: Option<String>,
domains: Vec<String>,
) -> String {
RandomGenerator::get_random_email_one_time(
num_names,
num_numbers,
separator,
domains,
&mut None::<RNG>,
)
}
#[cfg(feature = "names")]
#[allow(clippy::needless_pass_by_value)] pub fn get_random_email_one_time(
num_names: Option<usize>,
num_numbers: Option<usize>,
separator: Option<String>,
domains: Vec<String>,
gen: &mut Option<impl RngCore>,
) -> String {
let num_names = num_names.unwrap_or(2);
let num_numbers = num_numbers.unwrap_or(3);
let separator = separator.unwrap_or_default();
let mut str = String::new();
let username = RandomGenerator::get_random_username_one_time(
Some(num_names),
Some(num_numbers),
Some(separator.clone()),
gen,
);
str.push_str(username.as_str());
str.push('@');
let num_domains = domains.len();
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
let pick_domain = rng.gen_range(0..num_domains);
str.push_str(domains.get(pick_domain).unwrap().as_str());
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
let pick_domain = rng.gen_range(0..num_domains);
str.push_str(domains.get(pick_domain).unwrap().as_str());
} else {
let mut rng = StdRng::from_entropy();
let pick_domain = rng.gen_range(0..num_domains);
str.push_str(domains.get(pick_domain).unwrap().as_str());
}
}
str
}
#[cfg(feature = "names")]
pub fn get_simple_random_username_one_time(
num_names: Option<usize>,
num_numbers: Option<usize>,
separator: Option<String>,
) -> String {
RandomGenerator::get_random_username_one_time(
num_names,
num_numbers,
separator,
&mut None::<RNG>,
)
}
#[cfg(feature = "names")]
pub fn get_random_username_one_time(
num_names: Option<usize>,
num_numbers: Option<usize>,
separator: Option<String>,
gen: &mut Option<impl RngCore>,
) -> String {
let names_count = names::NAMES.len();
let num_names = num_names.unwrap_or(2);
let num_numbers = num_numbers.unwrap_or(5);
let separator = separator.unwrap_or_default();
let mut str = String::new();
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
for counter in 0..num_names {
let value: usize = rng.gen_range(0..names_count);
if counter > 0 {
str.push_str(separator.as_str());
}
str.push_str(names::NAMES[value].to_lowercase().as_str());
}
if num_numbers > 0 {
str.push_str(separator.as_str());
}
for _ in 0..num_numbers {
let value: u8 = rng.gen_range(48..57);
str.push(char::from(value));
}
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
for counter in 0..num_names {
let value: usize = rng.gen_range(0..names_count);
if counter > 0 {
str.push_str(separator.as_str());
}
str.push_str(names::NAMES[value].to_lowercase().as_str());
}
if num_numbers > 0 {
str.push_str(separator.as_str());
}
for _ in 0..num_numbers {
let value: u8 = rng.gen_range(48..57);
str.push(char::from(value));
}
} else {
let mut rng = StdRng::from_entropy();
for counter in 0..num_names {
let value: usize = rng.gen_range(0..names_count);
if counter > 0 {
str.push_str(separator.as_str());
}
str.push_str(names::NAMES[value].to_lowercase().as_str());
}
if num_numbers > 0 {
str.push_str(separator.as_str());
}
for _ in 0..num_numbers {
let value: u8 = rng.gen_range(48..57);
str.push(char::from(value));
}
}
}
str
}
#[cfg(feature = "names")]
pub fn get_simple_random_name_one_time() -> String {
RandomGenerator::get_random_name_one_time(&mut None::<RNG>)
}
#[cfg(feature = "names")]
pub fn get_random_name_one_time(gen: &mut Option<impl RngCore>) -> String {
let names_count = names::NAMES.len();
let mut str = String::new();
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
let value: usize = rng.gen_range(0..names_count);
str.push_str(names::NAMES[value]);
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
let value: usize = rng.gen_range(0..names_count);
str.push_str(names::NAMES[value]);
} else {
let mut rng = StdRng::from_entropy();
let value: usize = rng.gen_range(0..names_count);
str.push_str(names::NAMES[value]);
}
}
str
}
#[cfg(feature = "names")]
pub fn get_simple_random_first_name_one_time() -> String {
RandomGenerator::get_random_first_name_one_time(&mut None::<RNG>)
}
#[cfg(feature = "first_names")]
pub fn get_random_first_name_one_time(gen: &mut Option<impl RngCore>) -> String {
let names_count = first_names::FIRSTNAMES.len();
let mut str = String::new();
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
let value: usize = rng.gen_range(0..names_count);
str.push_str(to_title_case(first_names::FIRSTNAMES[value]).as_str());
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
let value: usize = rng.gen_range(0..names_count);
str.push_str(to_title_case(first_names::FIRSTNAMES[value]).as_str());
} else {
let mut rng = StdRng::from_entropy();
let value: usize = rng.gen_range(0..names_count);
str.push_str(to_title_case(first_names::FIRSTNAMES[value]).as_str());
}
}
str
}
#[cfg(feature = "names")]
pub fn get_simple_random_last_name_one_time() -> String {
RandomGenerator::get_random_last_name_one_time(&mut None::<RNG>)
}
#[cfg(feature = "last_names")]
pub fn get_random_last_name_one_time(gen: &mut Option<impl RngCore>) -> String {
let names_count = last_names::LASTNAMES.len();
let mut str = String::new();
#[cfg(all(
feature = "constrained",
all(not(feature = "core"), not(feature = "send_only"))
))]
{
match gen {
Some(rng) => {
let value: usize = rng.gen_range(0..names_count);
str.push_str(to_title_case(last_names::LASTNAMES[value]).as_str());
}
None => panic!("No generator provided"),
}
}
#[cfg(any(feature = "core", feature = "send_only"))]
{
if let Some(rng) = gen {
let value: usize = rng.gen_range(0..names_count);
str.push_str(to_title_case(last_names::LASTNAMES[value]).as_str());
} else {
let mut rng = StdRng::from_entropy();
let value: usize = rng.gen_range(0..names_count);
str.push_str(to_title_case(last_names::LASTNAMES[value]).as_str());
}
}
str
}
}
#[cfg(feature = "rand")]
impl RandomGeneratorTemplate for RandomGenerator {
fn get_random_bytes(&mut self, len: usize) -> Vec<u8> {
let mut bytes = vec![0u8; len];
self.generator.fill_bytes(&mut bytes);
bytes
}
fn get_random_usize(&mut self, min: usize, max: usize) -> usize {
self.generator.gen_range(min..=max)
}
fn get_random_u32(&mut self) -> u32 {
self.generator.next_u32()
}
fn get_random_u64(&mut self) -> u64 {
self.generator.next_u64()
}
fn get_random_string(&mut self, len: usize) -> String {
let mut str = String::with_capacity(len);
for _ in 0..len {
let value: u8 = self.generator.gen_range(33..=122);
let filtered = filter_printable_char(value);
str.push(char::from(filtered));
}
str
}
fn get_random_from_characters(&mut self, len: usize, characters: &str) -> String {
let mut str = String::with_capacity(len);
let char_vec: Vec<char> = characters.chars().collect();
let char_count = char_vec.len();
for _ in 0..len {
let ch = char_vec[self.generator.gen_range(0..char_count)];
str.push(ch);
}
str
}
fn get_random_alphanumeric(&mut self, len: usize) -> String {
let mut str = String::with_capacity(len);
for _ in 0..len {
let value: u8 = self.generator.gen_range(48..=122);
let filtered = filter_alphanumeric_char(value);
str.push(char::from(filtered));
}
str
}
fn generate_key(&mut self, len: usize) -> Vec<u8> {
let mut key = Vec::with_capacity(len);
for _ in 0..len {
key.push(self.generator.gen());
}
key
}
}
pub trait RandomGeneratorTemplate {
fn get_random_bytes(&mut self, len: usize) -> Vec<u8>;
fn get_random_usize(&mut self, min: usize, max: usize) -> usize;
fn get_random_u32(&mut self) -> u32;
fn get_random_u64(&mut self) -> u64;
fn get_random_string(&mut self, len: usize) -> String;
fn get_random_from_characters(&mut self, len: usize, characters: &str) -> String;
fn get_random_alphanumeric(&mut self, len: usize) -> String;
fn generate_key(&mut self, len: usize) -> Vec<u8>;
}
#[cfg(any(feature = "core", feature = "send_only", feature = "constrained"))]
pub fn random_usize(min: usize, max: usize) -> usize {
RandomGenerator::get_simple_random_usize_one_time(min, max)
}
#[cfg(any(feature = "core", feature = "send_only", feature = "constrained"))]
pub fn random_string(len: usize) -> String {
RandomGenerator::get_simple_random_string_one_time(len)
}
#[cfg(any(feature = "core", feature = "send_only", feature = "constrained"))]
pub fn random_alphanumeric(len: usize) -> String {
RandomGenerator::get_simple_random_alphanumeric_one_time(len)
}
#[cfg(any(feature = "core", feature = "send_only", feature = "constrained"))]
pub fn random_bytes(len: usize) -> Vec<u8> {
RandomGenerator::get_simple_random_bytes_one_time(len)
}
#[cfg(any(feature = "core", feature = "send_only", feature = "constrained"))]
pub fn random_password(len: usize) -> String {
RandomGenerator::get_simple_random_password_one_time(len)
}
#[cfg(any(feature = "core", feature = "send_only", feature = "constrained"))]
pub fn random_from_characters(len: usize, characters: &str) -> String {
RandomGenerator::get_simple_random_from_characters_one_time(len, characters)
}
#[cfg(any(feature = "core", feature = "send_only", feature = "constrained"))]
pub fn generate_random_key(len: usize) -> Vec<u8> {
RandomGenerator::generate_simple_key_one_time(len)
}