random_manager/
lib.rs

1use std::{
2    env,
3    io::{self, Error, ErrorKind},
4};
5
6use lazy_static::lazy_static;
7use primitive_types::{H160, H256, U256};
8use rand::Rng;
9use ring::rand::{SecureRandom, SystemRandom};
10
11/// Generates a random string of length "n".
12pub fn secure_string(n: usize) -> String {
13    let bytes = secure_bytes(n).unwrap();
14    let mut d = bs58::encode(&bytes[..]).into_string();
15    if n > 0 && d.len() > n {
16        d.truncate(n);
17    }
18    d
19}
20
21/// Generates a random string of length "n".
22pub fn secure_bytes(n: usize) -> io::Result<Vec<u8>> {
23    let mut d: Vec<u8> = vec![0u8; n];
24    secure_random()
25        .fill(&mut d)
26        .map_err(|e| Error::new(ErrorKind::Other, format!("failed secure_random.fill {}", e)))?;
27    Ok(d)
28}
29
30fn secure_random() -> &'static dyn SecureRandom {
31    use std::ops::Deref;
32    lazy_static! {
33        static ref RANDOM: SystemRandom = SystemRandom::new();
34    }
35    RANDOM.deref()
36}
37
38/// RUST_LOG=debug cargo test --package random-manager --lib -- test_secure_string --exact --show-output
39#[test]
40fn test_secure_string() {
41    use log::info;
42    let _ = env_logger::builder()
43        .filter_level(log::LevelFilter::Info)
44        .is_test(true)
45        .try_init();
46
47    let word1 = secure_string(100);
48    let word2 = secure_string(100);
49
50    assert_eq!(word1.len(), 100);
51    assert_eq!(word2.len(), 100);
52    assert_ne!(word1, word2);
53
54    info!("word1: {:?}", word1);
55    info!("word2: {:?}", word2);
56}
57
58/// Returns a file path randomly generated in tmp directory.
59/// The file does not exist yet.
60pub fn tmp_path(n: usize, sfx: Option<&str>) -> io::Result<String> {
61    let tmp_dir = env::temp_dir();
62    let tmp_file_path = tmp_dir.join(format!("{}{}", secure_string(n), sfx.unwrap_or("")));
63    let tmp_file_path = tmp_file_path.as_os_str().to_str().unwrap();
64    Ok(String::from(tmp_file_path))
65}
66
67/// RUST_LOG=debug cargo test --package random-manager --lib -- test_temp_path --exact --show-output
68#[test]
69fn test_temp_path() {
70    let _ = env_logger::builder()
71        .filter_level(log::LevelFilter::Info)
72        .is_test(true)
73        .try_init();
74
75    let p1 = tmp_path(10, Some(".zstd")).unwrap();
76    let p2 = tmp_path(10, Some(".zstd")).unwrap();
77    assert_ne!(p1, p2);
78
79    log::info!("p1: {:?}", p1);
80    log::info!("p2: {:?}", p2);
81}
82
83pub fn secure_u8() -> io::Result<u8> {
84    let mut d: Vec<u8> = vec![0u8; 1];
85    secure_random()
86        .fill(&mut d)
87        .map_err(|e| Error::new(ErrorKind::Other, format!("failed secure_random.fill {}", e)))?;
88    Ok(d[0])
89}
90
91pub fn usize() -> usize {
92    let mut rng = rand::thread_rng();
93    rng.gen()
94}
95
96pub fn u8() -> u8 {
97    let mut rng = rand::thread_rng();
98    rng.gen()
99}
100
101pub fn u16() -> u16 {
102    let mut rng = rand::thread_rng();
103    rng.gen()
104}
105
106pub fn u32() -> u32 {
107    let mut rng = rand::thread_rng();
108    rng.gen()
109}
110
111pub fn u64() -> u64 {
112    let mut rng = rand::thread_rng();
113    rng.gen()
114}
115
116/// RUST_LOG=debug cargo test --package random-manager --lib -- test_uints --exact --show-output
117#[test]
118fn test_uints() {
119    let _ = env_logger::builder()
120        .filter_level(log::LevelFilter::Info)
121        .is_test(true)
122        .try_init();
123
124    let v1 = usize();
125    let v2 = usize();
126    assert_ne!(v1, v2);
127    log::info!("v1: {v1}");
128    log::info!("v2: {v2}");
129
130    let v1 = u8();
131    let v2 = u8();
132    assert_ne!(v1, v2);
133    log::info!("v1: {v1}");
134    log::info!("v2: {v2}");
135
136    let v1 = u16();
137    let v2 = u16();
138    assert_ne!(v1, v2);
139    log::info!("v1: {v1}");
140    log::info!("v2: {v2}");
141
142    let v1 = u32();
143    let v2 = u32();
144    assert_ne!(v1, v2);
145    log::info!("v1: {v1}");
146    log::info!("v2: {v2}");
147
148    let v1 = u64();
149    let v2 = u64();
150    assert_ne!(v1, v2);
151    log::info!("v1: {v1}");
152    log::info!("v2: {v2}");
153}
154
155pub fn secure_h160() -> io::Result<H160> {
156    // MUST BE slice.len() < 4 * 5
157    let mut d: Vec<u8> = vec![0u8; 20];
158    secure_random()
159        .fill(&mut d)
160        .map_err(|e| Error::new(ErrorKind::Other, format!("failed secure_random.fill {}", e)))?;
161    Ok(H160::from_slice(&d))
162}
163
164/// RUST_LOG=debug cargo test --package random-manager --lib -- test_secure_h160 --exact --show-output
165#[test]
166fn test_secure_h160() {
167    let _ = env_logger::builder()
168        .filter_level(log::LevelFilter::Info)
169        .is_test(true)
170        .try_init();
171
172    let v1 = secure_h160().unwrap();
173    let v2 = secure_h160().unwrap();
174    assert_ne!(v1, v2);
175
176    log::info!("v1: 0x{:x}", v1);
177    log::info!("v2: 0x{:x}", v2);
178}
179
180pub fn secure_h256() -> io::Result<H256> {
181    let mut d: Vec<u8> = vec![0u8; 32];
182    secure_random()
183        .fill(&mut d)
184        .map_err(|e| Error::new(ErrorKind::Other, format!("failed secure_random.fill {}", e)))?;
185    Ok(H256::from_slice(&d))
186}
187
188/// RUST_LOG=debug cargo test --package random-manager --lib -- test_secure_h256 --exact --show-output
189#[test]
190fn test_secure_h256() {
191    let _ = env_logger::builder()
192        .filter_level(log::LevelFilter::Info)
193        .is_test(true)
194        .try_init();
195
196    let v1 = secure_h256().unwrap();
197    let v2 = secure_h256().unwrap();
198    assert_ne!(v1, v2);
199
200    log::info!("v1: 0x{:x}", v1);
201    log::info!("v2: 0x{:x}", v2);
202}
203
204pub fn secure_u256() -> io::Result<U256> {
205    // MUST BE slice.len() < 4 * 8
206    let mut d: Vec<u8> = vec![0u8; 32];
207    secure_random()
208        .fill(&mut d)
209        .map_err(|e| Error::new(ErrorKind::Other, format!("failed secure_random.fill {}", e)))?;
210    Ok(U256::from_big_endian(&d))
211}
212
213/// RUST_LOG=debug cargo test --package random-manager --lib -- test_secure_u256 --exact --show-output
214#[test]
215fn test_secure_u256() {
216    let _ = env_logger::builder()
217        .filter_level(log::LevelFilter::Info)
218        .is_test(true)
219        .try_init();
220
221    let v1 = secure_u256().unwrap();
222    let v2 = secure_u256().unwrap();
223    assert_ne!(v1, v2);
224
225    log::info!("v1: {v1}");
226    log::info!("v2: {v2}");
227}