1use std::io::Cursor;
2use std::sync::{Arc, Mutex};
3
4use arc_swap::ArcSwap;
5use byteorder::{BigEndian, ReadBytesExt};
6use hex::encode;
7use rand_chacha::rand_core::{RngCore, SeedableRng};
8use rand_chacha::ChaCha20Rng;
9
10thread_local! {
11 static RNG : ArcSwap<Mutex<ChaCha20Rng>> = ArcSwap::new(Arc::new(Mutex::new(ChaCha20Rng::seed_from_u64(11233429492))));
12}
13
14pub fn set_seed(seed: [u8; 32]) {
15 let mut seed = Cursor::new(seed.to_vec());
16 let seed = seed.read_u64::<BigEndian>().unwrap();
17 set_seed_u64(seed)
18}
19
20pub fn set_seed_u64(seed: u64) {
21 RNG.with(|v| {
22 v.swap(Arc::new(Mutex::new(ChaCha20Rng::seed_from_u64(seed))));
23 })
24}
25
26pub fn uuid16() -> String {
28 let bytes = RNG.with(|rng| {
29 let rng = rng.load();
30 let mut rng = rng.lock().unwrap();
31
32 let mut part_one: [u8; 4] = Default::default();
33 let mut part_two: [u8; 2] = Default::default();
34 let mut part_three: [u8; 2] = Default::default();
35 let mut part_four: [u8; 2] = Default::default();
36 let mut part_five: [u8; 6] = Default::default();
37
38 rng.fill_bytes(&mut part_one);
39
40 rng.fill_bytes(&mut part_two);
41 rng.fill_bytes(&mut part_three);
42 rng.fill_bytes(&mut part_four);
43 rng.fill_bytes(&mut part_five);
44 return (
45 encode(part_one), encode(part_two), encode(part_three), encode(part_four), encode(part_five), );
51 });
52
53 format!(
54 "{}-{}-{}-{}-{}",
55 bytes.0, bytes.1, bytes.2, bytes.3, bytes.4
56 )
57}
58
59#[test]
60fn test_uuid16() {
61 let id: String = uuid16();
62 println!("{}", id);
63 assert_eq!(id.len(), 36);
65}
66
67#[test]
69fn test_set_seed_u64() {
70 set_seed_u64(123);
71 let id: String = uuid16();
72 assert_eq!("d6daf4ca-bee9-f9f9-4b53-f7f1d8e813e4", id)
73}
74
75#[test]
77fn test_set_seed_bytes() {
78 set_seed([
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0,
81 ]);
82
83 let id: String = uuid16();
84 assert_eq!("b2f7f581-d6de-a822-7e82-c00f8401696a", id)
85}