code_rs/coding/
golay.rs

1//! Encoding and decoding of the (23, 12, 7) standard, (24, 12, 8) extended, and (18, 6,
2//! 8) shortened Golay codes described by P25.
3
4pub use cai_golay::{extended, standard};
5
6/// Encoding and decoding of the (18, 6, 8) code.
7pub mod shortened {
8    use super::*;
9
10    /// Encode the given 6 data bits to an 18-bit codeword.
11    pub fn encode(data: u8) -> u32 {
12        assert_eq!(data >> 6, 0);
13        extended::encode(data as u16)
14    }
15
16    /// Try to decode the given 18-bit word to the nearest codeword, correcting up to 3
17    /// errors.
18    ///
19    /// If decoding was successful, return `Some((data, err))`, where `data` is the 6
20    /// data bits and `err` is the number of corrected bits. Otherwise, return `None` to
21    /// indicate an unrecoverable error.
22    pub fn decode(word: u32) -> Option<(u8, usize)> {
23        assert_eq!(word >> 18, 0);
24
25        extended::decode(word).and_then(|(data, err)| {
26            if data >> 6 == 0 {
27                Some((data as u8, err))
28            } else {
29                None
30            }
31        })
32    }
33}
34
35#[cfg(test)]
36mod test {
37    use super::*;
38
39    #[test]
40    fn test_shortened() {
41        assert_eq!(shortened::encode(0), 0);
42        assert_eq!(shortened::encode(0b111111), 0b11_1111_0011_0010_1110);
43        assert_eq!(shortened::encode(0b000111), 0b00_0111_1011_0100_0010);
44        assert_eq!(shortened::encode(0b111000), 0b11_1000_1000_0110_1100);
45        assert_eq!(shortened::encode(0b100001), 0b10_0001_1110_0010_0110);
46
47        let w = 0b101010;
48        let e = shortened::encode(w);
49        assert_eq!(e, 0b10_1010_0010_0011_0101);
50
51        assert_eq!(shortened::decode(e ^ 0b100000000000000001), Some((w, 2)));
52        assert_eq!(shortened::decode(e ^ 0b010000000000000010), Some((w, 2)));
53        assert_eq!(shortened::decode(e ^ 0b001000000000000100), Some((w, 2)));
54        assert_eq!(shortened::decode(e ^ 0b000100000000001000), Some((w, 2)));
55        assert_eq!(shortened::decode(e ^ 0b000010000000010000), Some((w, 2)));
56        assert_eq!(shortened::decode(e ^ 0b000001000000100000), Some((w, 2)));
57        assert_eq!(shortened::decode(e ^ 0b000000100001000000), Some((w, 2)));
58        assert_eq!(shortened::decode(e ^ 0b000000010010000000), Some((w, 2)));
59        assert_eq!(shortened::decode(e ^ 0b000000001100000000), Some((w, 2)));
60        assert_eq!(shortened::decode(e ^ 0b000000000101000000), Some((w, 2)));
61        assert_eq!(shortened::decode(e ^ 0b000000001000100000), Some((w, 2)));
62        assert_eq!(shortened::decode(e ^ 0b000000010000010000), Some((w, 2)));
63        assert_eq!(shortened::decode(e ^ 0b000000100000001000), Some((w, 2)));
64        assert_eq!(shortened::decode(e ^ 0b000001000000000100), Some((w, 2)));
65        assert_eq!(shortened::decode(e ^ 0b000010000000000010), Some((w, 2)));
66        assert_eq!(shortened::decode(e ^ 0b000100000000000001), Some((w, 2)));
67        assert_eq!(shortened::decode(e ^ 0b001000000000000100), Some((w, 2)));
68        assert_eq!(shortened::decode(e ^ 0b010000000000010000), Some((w, 2)));
69        assert_eq!(shortened::decode(e ^ 0b100000000000100000), Some((w, 2)));
70
71        assert_eq!(shortened::decode(e ^ 0b111000000000000000), Some((w, 3)));
72        assert_eq!(shortened::decode(e ^ 0b011100000000000000), Some((w, 3)));
73        assert_eq!(shortened::decode(e ^ 0b001110000000000000), Some((w, 3)));
74        assert_eq!(shortened::decode(e ^ 0b000111000000000000), Some((w, 3)));
75        assert_eq!(shortened::decode(e ^ 0b000011100000000000), Some((w, 3)));
76        assert_eq!(shortened::decode(e ^ 0b000001110000000000), Some((w, 3)));
77        assert_eq!(shortened::decode(e ^ 0b000000111000000000), Some((w, 3)));
78        assert_eq!(shortened::decode(e ^ 0b000000011100000000), Some((w, 3)));
79        assert_eq!(shortened::decode(e ^ 0b000000001110000000), Some((w, 3)));
80        assert_eq!(shortened::decode(e ^ 0b000000000111000000), Some((w, 3)));
81        assert_eq!(shortened::decode(e ^ 0b000000000011100000), Some((w, 3)));
82        assert_eq!(shortened::decode(e ^ 0b000000000001110000), Some((w, 3)));
83        assert_eq!(shortened::decode(e ^ 0b000000000000111000), Some((w, 3)));
84        assert_eq!(shortened::decode(e ^ 0b000000000000011100), Some((w, 3)));
85        assert_eq!(shortened::decode(e ^ 0b000000000000001110), Some((w, 3)));
86        assert_eq!(shortened::decode(e ^ 0b000000000000000111), Some((w, 3)));
87
88        assert_eq!(shortened::decode(e ^ 0b000000000000000000), Some((w, 0)));
89        assert_eq!(shortened::decode(e ^ 0b000000000000000001), Some((w, 1)));
90        assert_eq!(shortened::decode(e ^ 0b000000000000000011), Some((w, 2)));
91        assert_eq!(shortened::decode(e ^ 0b000000000000000111), Some((w, 3)));
92        assert_eq!(shortened::decode(e ^ 0b000100000000000000), Some((w, 1)));
93        assert_eq!(shortened::decode(e ^ 0b001100000000000000), Some((w, 2)));
94        assert_eq!(shortened::decode(e ^ 0b011100000000000000), Some((w, 3)));
95        assert_eq!(shortened::decode(e ^ 0b001100000000000010), Some((w, 3)));
96        assert_eq!(shortened::decode(e ^ 0b001000000000000110), Some((w, 3)));
97    }
98}