dl_uuid/
lib.rs

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
26/// Generates 16-byte UUID as a String
27pub 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),   //4
46            encode(part_two),   //2
47            encode(part_three), //2
48            encode(part_four),  //2
49            encode(part_five),  //6
50        );
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    // 16 * 2 bytes + 4 dashes
64    assert_eq!(id.len(), 36);
65}
66
67// Check against known value
68#[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// Check against known value
76#[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}