ps_uuid/methods/
gen_v4.rs1use rand::fill;
2
3use crate::UUID;
4
5impl UUID {
6 #[must_use]
8 pub fn gen_v4() -> Self {
9 let mut uuid = Self::nil();
10
11 fill(&mut uuid.bytes);
12
13 uuid.with_version(4)
14 }
15}
16
17#[cfg(test)]
18mod tests {
19 use super::UUID;
20 use std::collections::HashSet;
21
22 #[test]
23 fn version_and_variant_are_set() {
24 for _ in 0..100 {
25 let uuid = UUID::gen_v4();
26 assert_eq!(uuid.bytes[6] >> 4, 0b0100, "Version must be 4");
28 assert_eq!(
30 uuid.bytes[8] & 0b1100_0000,
31 0b1000_0000,
32 "Variant must be RFC 4122"
33 );
34 }
35 }
36
37 #[test]
38 fn randomness_produces_unique_uuids() {
39 let mut set = HashSet::new();
40 for _ in 0..1000 {
41 let uuid = UUID::gen_v4();
42 assert!(set.insert(uuid.bytes), "Duplicate UUID generated!");
43 }
44 }
45
46 #[test]
47 fn all_other_bits_are_random() {
48 let mut seen = [0u8; 16];
51 let mut seen_inv = [0xFFu8; 16];
52
53 for _ in 0..1000 {
54 let uuid = UUID::gen_v4();
55 for i in 0..16 {
56 seen[i] |= uuid.bytes[i];
57 seen_inv[i] &= uuid.bytes[i];
58 }
59 }
60
61 assert_ne!(
63 seen[6] & 0x0F,
64 0,
65 "At least one lower bit in byte 6 should be 1"
66 );
67 assert_ne!(
68 seen_inv[6] & 0x0F,
69 0x0F,
70 "At least one lower bit in byte 6 should be 0"
71 );
72 assert_ne!(
74 seen[8] & 0x3F,
75 0,
76 "At least one lower bit in byte 8 should be 1"
77 );
78 assert_ne!(
79 seen_inv[8] & 0x3F,
80 0x3F,
81 "At least one lower bit in byte 8 should be 0"
82 );
83 for i in 0..16 {
85 if i == 6 {
86 assert_eq!(seen[6] & 0xF0, 0x40, "Version bits must be set to 4");
88 } else if i == 8 {
89 assert_eq!(seen[8] & 0xC0, 0x80, "Variant bits must be set to RFC 4122");
91 } else {
92 assert_ne!(seen[i], 0, "At least one bit in byte {i} should be 1");
93 assert_ne!(
94 seen_inv[i], 0xFF,
95 "At least one bit in byte {i} should be 0"
96 );
97 }
98 }
99 }
100
101 #[test]
102 fn version_and_variant_methods_report_correctly() {
103 let uuid = UUID::gen_v4();
104 assert_eq!(uuid.get_version(), Some(4));
105 }
107}