Skip to main content

lfsr_fibo/
lib.rs

1use std::collections::VecDeque;
2
3/// Structure representing a Fibonacci LFSR
4#[derive(Debug, Clone, Hash)]
5pub struct Lfsr {
6    state: VecDeque<u8>,
7    taps: Vec<u8>,
8}
9
10
11impl Lfsr {
12    /// Return a new LFSR from given taps.
13    ///
14    /// # Example
15    ///
16    /// If the fibonacci polynomial representing your LFSR is x^19 + x^13 + x^2 + 1,
17    /// then you could get that LFSR using :
18    ///
19    /// ```
20    /// let lfsr = Lfsr::new(vec![19, 13, 2]);
21    /// ```
22    pub fn new(taps: Vec<u8>) -> Lfsr {
23        Lfsr {
24            state: VecDeque::new(),
25            taps: taps.into_iter().map(|t| t-1).collect(),
26        }
27    }
28    
29    /// Set the key of the LFSR
30    ///
31    /// # Example
32    /// 
33    /// Let say that your key is [0, 1, 1, 0, 0, 0, 1], then :
34    ///
35    /// ```
36    /// let mut lfsr = Lfsr::new(vec![7, 5, 2]);
37    /// let key: VecDeque<u8> = VecDeque::from([0, 1, 1, 0, 0, 0, 1]);
38    /// 
39    /// lfsr.set_key(key);
40    /// ```
41    pub fn set_key(&mut self, key:VecDeque<u8>) {
42        self.state = key;
43    }
44
45    /// Internal function that compute the carry of the LFSR
46    /// i.e the XOR of all the state elements referenced in the taps.
47    fn _carry(&self) -> u8{
48        self.taps.iter().map(|&i| self.state[i as usize]).sum::<u8>() & 1
49    }
50
51    /// Clock the LFSR once and output the bit as an u8.
52    ///
53    /// # Example
54     /// Let say that your key is [0, 1, 1, 0, 0, 0, 1], then :
55    ///
56    /// ```
57    /// let mut lfsr = Lfsr::new(vec![7, 5, 2]);
58    /// let key: VecDeque<u8> = VecDeque::from([0, 1, 1, 0, 0, 0, 1]);
59    /// 
60    /// lfsr.set_key(key);
61    /// println!("First bit is : {:?}", lfsr.clock());
62    /// ```
63    pub fn clock(&mut self) -> u8 {
64        self.state.push_front(self._carry());
65        self.state.pop_back().unwrap()
66    }
67}