1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use crate::RandomNumberGenerator;
use rand::{CryptoRng, RngCore};
use rand_xoshiro::rand_core::SeedableRng;
use rand_xoshiro::Xoshiro256StarStar;

/// A random number generator that can be used as a source of deterministic pseudo-randomness
/// for testing purposes.
#[derive(Debug, Clone)]
pub struct SeededRandomNumberGenerator {
    rng: Xoshiro256StarStar
}

impl SeededRandomNumberGenerator {
    /// Creates a new seeded random number generator.
    ///
    /// The seed should be a 256-bit value, represented as an array of 4 64-bit integers.
    /// For the output distribution to look random, the seed should not have any obvious
    /// patterns, like all zeroes or all ones.
    ///
    /// This is not cryptographically secure, and should only be used for testing purposes.
    pub fn new(seed: [u64; 4]) -> Self {
        let mut seed_bytes = [0u8; 32];
        for i in 0..4 {
            seed_bytes[i * 8..(i + 1) * 8].copy_from_slice(&seed[i].to_le_bytes());
        }
        Self {
            rng: Xoshiro256StarStar::from_seed(seed_bytes)
        }
    }

    pub fn next_u64(&mut self) -> u64 {
        self.rng.next_u64()
    }
}

impl RngCore for SeededRandomNumberGenerator {
    fn next_u32(&mut self) -> u32 {
        self.next_u64() as u32
    }

    fn next_u64(&mut self) -> u64 {
        self.rng.next_u64()
    }

    fn fill_bytes(&mut self, dest: &mut [u8]) {
        self.rng.fill_bytes(dest);
    }

    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
        self.rng.fill_bytes(dest);
        Ok(())
    }
}

// Note that we implement `CryptoRng` for `SeededRandomNumberGenerator` because it is required
// by the some third-party crates, but this is NOT a cryptographically secure random number generator.
// `SeededRandomNumberGenerator` should only be used for testing purposes.
impl CryptoRng for SeededRandomNumberGenerator {}

impl RandomNumberGenerator for SeededRandomNumberGenerator {
    fn random_data(&mut self, size: usize) -> Vec<u8> {
        // This might not be the most efficient implementation,
        // but it works the same as the Swift version.
        (0..size).map(|_| self.next_u64() as u8).collect()
    }

    fn fill_random_data(&mut self, data: &mut [u8]) {
        data.iter_mut().for_each(|x| *x = self.next_u64() as u8);
    }
}

/// Creates a seeded random number generator with a fixed seed.
pub fn make_fake_random_number_generator() -> impl RandomNumberGenerator {
    SeededRandomNumberGenerator::new([17295166580085024720, 422929670265678780, 5577237070365765850, 7953171132032326923])
}

/// Creates a vector of random data with a fixed seed.
pub fn fake_random_data(size: usize) -> Vec<u8> {
    make_fake_random_number_generator().random_data(size)
}

#[cfg(test)]
mod tests {
    use crate::{fake_random_data , rng_next_in_range, rng_next_with_upper_bound, RandomNumberGenerator, SeededRandomNumberGenerator};

    const TEST_SEED: [u64; 4] = [17295166580085024720, 422929670265678780, 5577237070365765850, 7953171132032326923];

    #[test]
    fn test_next_u64() {
        let mut rng = SeededRandomNumberGenerator::new(TEST_SEED);
        assert_eq!(rng.next_u64(), 1104683000648959614);
    }

    #[test]
    fn test_next_50() {
        let mut rng = SeededRandomNumberGenerator::new(TEST_SEED);
        let expected_values: Vec<u64> = vec![1104683000648959614, 9817345228149227957, 546276821344993881, 15870950426333349563, 830653509032165567, 14772257893953840492, 3512633850838187726, 6358411077290857510, 7897285047238174514, 18314839336815726031, 4978716052961022367, 17373022694051233817, 663115362299242570, 9811238046242345451, 8113787839071393872, 16155047452816275860, 673245095821315645, 1610087492396736743, 1749670338128618977, 3927771759340679115, 9610589375631783853, 5311608497352460372, 11014490817524419548, 6320099928172676090, 12513554919020212402, 6823504187935853178, 1215405011954300226, 8109228150255944821, 4122548551796094879, 16544885818373129566, 5597102191057004591, 11690994260783567085, 9374498734039011409, 18246806104446739078, 2337407889179712900, 12608919248151905477, 7641631838640172886, 8421574250687361351, 8697189342072434208, 8766286633078002696, 14800090277885439654, 17865860059234099833, 4673315107448681522, 14288183874156623863, 7587575203648284614, 9109213819045273474, 11817665411945280786, 1745089530919138651, 5730370365819793488, 5496865518262805451];
        assert!(expected_values.into_iter().all(|x| x == rng.next_u64()));
    }

    #[test]
    fn test_fake_random_data() {
        assert_eq!(fake_random_data(100), hex_literal::hex!("7eb559bbbf6cce2632cf9f194aeb50943de7e1cbad54dcfab27a42759f5e2fed518684c556472008a67932f7c682125b50cb72e8216f6906358fdaf28d3545532daee0c5bb5023f50cd8e71ec14901ac746c576c481b893be6656b80622b3a564e59b4e2"));
    }

    #[test]
    fn test_next_with_upper_bound() {
        let mut rng = SeededRandomNumberGenerator::new(TEST_SEED);
        assert_eq!(rng_next_with_upper_bound(&mut rng, 10000u32), 745);
    }

    #[test]
    fn test_in_range() {
        let mut rng = SeededRandomNumberGenerator::new(TEST_SEED);
        let v = (0..100).map(|_| rng_next_in_range(&mut rng, &(0..100))).collect::<Vec<_>>();
        let expected_values: Vec<i32> = vec![7, 44, 92, 16, 16, 67, 41, 74, 66, 20, 18, 6, 62, 34, 4, 69, 99, 19, 0, 85, 22, 27, 56, 23, 19, 5, 23, 76, 80, 27, 74, 69, 17, 92, 31, 32, 55, 36, 49, 23, 53, 2, 46, 6, 43, 66, 34, 71, 64, 69, 25, 14, 17, 23, 32, 6, 23, 65, 35, 11, 21, 37, 58, 92, 98, 8, 38, 49, 7, 24, 24, 71, 37, 63, 91, 21, 11, 66, 52, 54, 55, 19, 76, 46, 89, 38, 91, 95, 33, 25, 4, 30, 66, 51, 5, 91, 62, 27, 92, 39];
        assert_eq!(v, expected_values);
    }

    #[test]
    fn test_fill_random_data() {
        let mut rng = SeededRandomNumberGenerator::new(TEST_SEED);
        let v1 = rng.random_data(100);
        let mut rng = SeededRandomNumberGenerator::new(TEST_SEED);
        let mut v2 = [0u8; 100];
        rng.fill_random_data(&mut v2);
        assert_eq!(v1, v2);
    }
}