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
/// Unpack an unsigned integer into a binary sequence of {0,1} u8
/// This function is meant to provide seed/initialisation values for M-sequence generators.
/// __Example__
/// ```
/// use aether_primitives::sequence;
/// // set bits 1,3,5
/// let seed = 1 + 4 + 16;
/// // take 32 values from that
/// let expanded = sequence::expand(seed, 32);
/// let mut expected = vec![0u8; 32];
/// expected.iter_mut().zip([1,0,1,0,1].iter())
/// .for_each(|(s,x)| *s = *x as u8);
///
/// assert_eq!(expanded, expected, "Seed expansion failed");
/// assert_eq!(expanded.len(), 32usize)
/// ```
pub fn expand(seed: u64, len: usize) -> Vec<u8> {
// left shift seed value and use binary & to extract the bit we're interested in
(0..len).map(|i| (seed >> i & 1) as u8).collect()
}
/// Generate a M-Sequence based on initial values and a number of taps
/// Such sequences are common building blocks for scrambling, synchronisation or modulation
/// (Direct-Sequence Spread-Spectrum) systems.
/// ```seed``` :
/// ```generator```: a function that generates elements,
/// may rely on values currently within the sequence,
// is also provided the current position to be filled by the new value
/// ```len``` : length of the
/// __Example__
/// ```
/// use aether_primitives::sequence;
/// // This example generates one half of the pseudo-random sequence
/// // used by LTE's physical layer as per 3GPP TS36.211 7.2
/// // It is provided in the form
/// // ``` x1(n+31) = (x1(n+3) + x1(n)) mod2 ```
/// // Since we use an array to generate that we need to indices
/// // Every step should yield one x(n) with n in [32..1600]
/// // ```x(n) = (x(n+3-31) + x(n-31)) mod2 ```
/// // Thus our generator is this
/// let gen = |n : usize, seq : &[u8] | (seq[n-28] + seq[n-31]) % 2;
/// // get an init vector
/// let mut init = sequence::expand(1,31);
/// let seq = sequence::generate(init, gen, 1600);
/// assert_eq!(seq.len(), 1600);
/// // not going to check these values here
pub fn generate(mut init: Vec<u8>, generator: impl Fn(usize, &[u8]) -> u8, len: usize) -> Vec<u8> {
while init.len() < len {
let next_elem = generator(init.len(), init.as_ref());
init.push(next_elem);
}
init
}
#[cfg(test)]
mod test {
use crate::sequence;
#[test]
/// A simple sequence
fn simple_sequence() {
let gen = |n: usize, s: &[u8]| (s[n - 1] + s[n - 2]) % 2;
let seed = vec![1, 0];
let seq = sequence::generate(seed, gen, 6);
assert_eq!(seq, vec![1, 0, 1, 1, 0, 1]);
}
}