use std::sync::{Mutex, OnceLock};
use rand::{Rng, SeedableRng, rngs::SmallRng};
static COUNTER: OnceLock<Mutex<u32>> = OnceLock::new();
pub fn next_3byte_be() -> [u8; 3] {
COUNTER.get_or_init(|| {
let seed_u64 = try_seed_from_os();
let mut rng = SmallRng::seed_from_u64(seed_u64);
let initial = rng.next_u32() & 0x00FF_FFFF;
Mutex::new(initial)
});
let mut guard = COUNTER.get().unwrap().lock().unwrap();
let cur = *guard;
let ret = cur as u32;
*guard = (cur.wrapping_add(1)) & 0x00FF_FFFF;
[(ret >> 16) as u8, (ret >> 8) as u8, (ret) as u8]
}
fn try_seed_from_os() -> u64 {
let mut buf = [0u8; 8];
rand::rng().fill_bytes(&mut buf);
u64::from_le_bytes(buf)
}