rust/lfprng/src/lib.rs
author nemo
Tue, 30 Apr 2019 09:36:13 -0400
changeset 14859 8d65728c4ed0
parent 14152 5acfdf49742d
child 15115 de32299de704
permissions -rw-r--r--
Backed out changeset 13589d529899 So, we only disabled this on the release branch in r29d614a5c9eb due to having discovered it JUST before release. We should fix it properly in default...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13886
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
     1
pub struct LaggedFibonacciPRNG {
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
     2
    circular_buffer: [u32; 64],
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
     3
    index: usize,
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
     4
}
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
     5
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
     6
impl LaggedFibonacciPRNG {
14027
cef0c685fda8 make useful stuff public
alfadur
parents: 13935
diff changeset
     7
    pub fn new(init_values: &[u8]) -> Self {
13886
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
     8
        let mut buf = [0xa98765 + 68; 64];
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
     9
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    10
        for i in 0..std::cmp::min(init_values.len(), 54) {
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    11
            buf[i] = init_values[i] as u32;
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    12
        }
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    13
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    14
        let mut prng = Self {
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    15
            circular_buffer: buf,
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    16
            index: 54,
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    17
        };
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    18
14152
5acfdf49742d Fix some warnings here and there, remove unwelcomed code
unC0Rr
parents: 14029
diff changeset
    19
        for _i in 0..2048 {
13886
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    20
            prng.get_next();
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    21
        }
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    22
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    23
        prng
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    24
    }
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    25
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    26
    #[inline]
14029
259175ab7e8c hide get_next back
alfadur
parents: 14027
diff changeset
    27
    fn get_next(&mut self) -> u32 {
13886
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    28
        self.index = (self.index + 1) & 0x3f;
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    29
        self.circular_buffer[self.index] = (self.circular_buffer[(self.index + 40) & 0x3f]
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    30
            + self.circular_buffer[(self.index + 9) & 0x3f])
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    31
            & 0x7fffffff;
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    32
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    33
        self.circular_buffer[self.index]
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    34
    }
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    35
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    36
    #[inline]
14027
cef0c685fda8 make useful stuff public
alfadur
parents: 13935
diff changeset
    37
    pub fn get_random(&mut self, modulo: u32) -> u32 {
13886
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    38
        self.get_next();
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    39
        self.get_next() % modulo
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    40
    }
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    41
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    42
    #[inline]
14027
cef0c685fda8 make useful stuff public
alfadur
parents: 13935
diff changeset
    43
    pub fn add_randomness(&mut self, value: u32) {
13886
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    44
        self.index = (self.index + 1) & 0x3f;
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    45
        self.circular_buffer[self.index] ^= value;
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    46
    }
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    47
}
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    48
13904
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13886
diff changeset
    49
impl Iterator for LaggedFibonacciPRNG {
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13886
diff changeset
    50
    type Item = u32;
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13886
diff changeset
    51
13935
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents: 13904
diff changeset
    52
    fn next(&mut self) -> Option<Self::Item> {
13904
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13886
diff changeset
    53
        self.get_next();
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13886
diff changeset
    54
        Some(self.get_next())
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13886
diff changeset
    55
    }
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13886
diff changeset
    56
}
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13886
diff changeset
    57
13886
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    58
#[cfg(test)]
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    59
#[test]
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    60
fn compatibility() {
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    61
    let mut prng = LaggedFibonacciPRNG::new("{052e2aee-ce41-4720-97bd-559a413bf866}".as_bytes());
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    62
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    63
    assert_eq!(prng.get_random(1000), 418);
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    64
    assert_eq!(prng.get_random(1000000), 554064);
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    65
    assert_eq!(prng.get_random(0xffffffff), 239515837);
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    66
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    67
    prng.add_randomness(123);
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    68
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    69
    for i in 0..=100000 {
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    70
        prng.get_random(2);
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    71
    }
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    72
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    73
    assert_eq!(prng.get_random(0xffffffff), 525333582);
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    74
}