#[macro_export]
macro_rules! random_string {
($range:expr, $charset:expr => $string:expr) => {{
use ::rand::{distributions::Slice, Rng};
$string.extend(
::rand::thread_rng()
.sample_iter(Slice::new($charset).unwrap())
.take($range)
.map(|&c| c as char)
);
}};
($range:expr, $charset:expr) => {{
use ::rand::{distributions::Slice, Rng};
let mut string = String::with_capacity($range);
string.extend(
::rand::thread_rng()
.sample_iter(Slice::new($charset).unwrap())
.take($range)
.map(|&c| c as char)
);
string
}};
($range:expr => $string:expr) => {
$crate::random_string!($range, b"0123456789abcdef" => $string)
};
($range:expr) => {
$crate::random_string!($range, b"0123456789abcdef")
};
}
#[deprecated(since = "0.7.12", note = "Use `RandHexStr` instead")]
#[cfg(feature = "feat-string")]
#[macro_export]
macro_rules! random_string_fast {
($b:expr, $l:expr) => {{
use $crate::string::StringExtT;
$crate::string::NumStr::hex_default($crate::random::fast_random())
.set_uppercase::<$b>()
.to_string_ext()
}};
}
#[inline]
pub fn fast_random() -> u64 {
#[cfg(not(feature = "feat-random-fast"))]
use std::hash::RandomState;
use std::{
cell::Cell,
hash::{BuildHasher, Hasher},
num::Wrapping,
};
#[cfg(feature = "feat-random-fast")]
use ::foldhash::fast::RandomState;
thread_local! {
static RNG: Cell<Wrapping<u64>> = Cell::new(Wrapping(seed()));
}
fn seed() -> u64 {
let seed = RandomState::default();
let mut out = 0;
let mut cnt = 0;
while out == 0 {
cnt += 1;
let mut hasher = seed.build_hasher();
hasher.write_usize(cnt);
out = hasher.finish();
}
out
}
RNG.with(|rng| {
let mut n = rng.get();
debug_assert_ne!(n.0, 0);
n ^= n >> 12;
n ^= n << 25;
n ^= n >> 27;
rng.set(n);
n.0.wrapping_mul(0x2545_f491_4f6c_dd1d)
})
}
#[macro_export]
macro_rules! random_choice {
($range:expr, $choice_set:expr) => {{
let mut rng = ::rand::thread_rng();
let mut result = String::with_capacity(32);
(0..$range).for_each(|_| {
result.push_str($choice_set[::rand::Rng::gen_range(&mut rng, 0..$choice_set.len())]);
});
result
}};
($($range:expr),+; $split:expr; $choice_set:expr) => {{
let mut rng = ::rand::thread_rng();
let mut result = String::with_capacity(32);
$(
(0..$range).for_each(|_| {
result.push_str($choice_set[::rand::Rng::gen_range(&mut rng, 0..$choice_set.len())]);
});
result.push_str($split);
)+
result.truncate(result.len() - $split.len());
result
}};
}