use core::sync::atomic::{AtomicU64, Ordering};
#[cfg(feature = "std")]
use std::collections::hash_map::RandomState;
#[cfg(feature = "std")]
use std::hash::{BuildHasher, Hash, Hasher};
static NONCE_COUNTER: AtomicU64 = AtomicU64::new(0);
#[cfg(feature = "std")]
pub fn nonce_u64() -> [u8; 8] {
let duration_since_epoch = std::time::SystemTime::now()
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.unwrap();
let nanos = duration_since_epoch.as_nanos();
#[allow(clippy::cast_possible_truncation)]
let from_time = ((nanos >> 64) as u64) ^ (nanos as u64) ^ duration_since_epoch.as_secs();
let from_counter = NONCE_COUNTER.fetch_add(1, Ordering::Relaxed);
let mut hasher = RandomState::new().build_hasher();
from_time.hash(&mut hasher);
from_counter.hash(&mut hasher);
(hasher.finish() ^ from_time ^ from_counter).to_ne_bytes()
}
#[cfg(not(feature = "std"))]
pub fn nonce_u64() -> [u8; 8] {
NONCE_COUNTER.fetch_add(1, Ordering::Relaxed).to_ne_bytes()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nonces_are_different() {
assert_ne!(nonce_u64(), nonce_u64());
}
}