rust/lfprng/src/lib.rs
author alfadur
Mon, 29 Oct 2018 23:40:17 +0300
changeset 14050 259175ab7e8c
parent 14048 cef0c685fda8
child 14173 5acfdf49742d
permissions -rw-r--r--
hide get_next back
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13910
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 {
14048
cef0c685fda8 make useful stuff public
alfadur
parents: 13956
diff changeset
     7
    pub fn new(init_values: &[u8]) -> Self {
13910
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
b6c35ac1c5ba Implement lagged Fibonacci PRNG in rust, compatible with hwengine
unc0rr
parents:
diff changeset
    19
        for i in 0..2048 {
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]
14050
259175ab7e8c hide get_next back
alfadur
parents: 14048
diff changeset
    27
    fn get_next(&mut self) -> u32 {
13910
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]
14048
cef0c685fda8 make useful stuff public
alfadur
parents: 13956
diff changeset
    37
    pub fn get_random(&mut self, modulo: u32) -> u32 {
13910
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]
14048
cef0c685fda8 make useful stuff public
alfadur
parents: 13956
diff changeset
    43
    pub fn add_randomness(&mut self, value: u32) {
13910
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
13925
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13910
diff changeset
    49
impl Iterator for LaggedFibonacciPRNG {
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13910
diff changeset
    50
    type Item = u32;
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13910
diff changeset
    51
13956
75eaf7c71789 Introduce integral-geometry crate, implement LinePoints iterator
unc0rr
parents: 13925
diff changeset
    52
    fn next(&mut self) -> Option<Self::Item> {
13925
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13910
diff changeset
    53
        self.get_next();
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13910
diff changeset
    54
        Some(self.get_next())
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13910
diff changeset
    55
    }
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13910
diff changeset
    56
}
3f0576157749 Implement Iterator trait for LaggedFibonacciPRNG
unc0rr
parents: 13910
diff changeset
    57
13910
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
}