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}