oxidite_security/
random.rs1use rand::Rng;
4use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
5
6pub fn random_bytes(length: usize) -> Vec<u8> {
8 let mut rng = rand::rng();
9 let mut bytes = vec![0u8; length];
10 rng.fill(&mut bytes[..]);
11 bytes
12}
13
14pub fn random_hex(length: usize) -> String {
16 hex::encode(random_bytes(length))
17}
18
19pub fn secure_token(bytes: usize) -> String {
21 URL_SAFE_NO_PAD.encode(random_bytes(bytes))
22}
23
24pub fn random_alphanumeric(length: usize) -> String {
26 const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
27 let mut rng = rand::rng();
28
29 (0..length)
30 .map(|_| {
31 let idx = rng.random_range(0..CHARSET.len());
32 CHARSET[idx] as char
33 })
34 .collect()
35}
36
37pub fn random_range(min: u64, max: u64) -> u64 {
39 let mut rng = rand::rng();
40 rng.random_range(min..max)
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_random_bytes() {
49 let bytes = random_bytes(32);
50 assert_eq!(bytes.len(), 32);
51 }
52
53 #[test]
54 fn test_random_hex() {
55 let hex_str = random_hex(16);
56 assert_eq!(hex_str.len(), 32); }
58
59 #[test]
60 fn test_secure_token() {
61 let token = secure_token(32);
62 assert!(token.len() > 40);
64 }
65
66 #[test]
67 fn test_random_range() {
68 for _ in 0..100 {
69 let n = random_range(10, 20);
70 assert!(n >= 10 && n < 20);
71 }
72 }
73}