entest/
mean.rs

1//! the Mean entropy test.
2
3use super::*;
4
5/// Computes the Mean Entropy test
6#[derive(Debug, Clone, Copy)]
7pub struct MeanCalculation {
8    pub(crate) buckets: [u64; 256],
9    pub(crate) total_buckets: u64,
10}
11
12impl Default for MeanCalculation {
13    #[inline(always)]
14    fn default() -> Self {
15        Self::INIT
16    }
17}
18
19impl MeanCalculation {
20    /// the blanket state (initial value) of [MeanCalculation].
21    pub const INIT: Self =
22        Self {
23            buckets: [0; 256],
24            total_buckets: 0,
25        };
26
27    /// create new blanket state for mean calculation.
28    ///
29    /// this just copy from [MeanCalculation::INIT].
30    pub const fn new() -> Self {
31        Self::INIT
32    }
33
34    /// apply byte stream to mean state.
35    pub const fn update(&mut self, bytes: &[u8]) -> &mut Self {
36        let mut i = 0;
37        let bytes_len = bytes.len();
38        while i < bytes_len {
39            self.buckets[bytes[i] as usize] += 1;
40            i += 1;
41        }
42        self.total_buckets += bytes_len as u64;
43
44        self
45    }
46
47    /// get finalize mean result of current byte stream.
48    #[inline(always)]
49    pub const fn finalize(&self) -> Dec {
50        if self.total_buckets == 0 {
51            return Dec::NAN;
52        }
53
54        let mut sum = dec!(0.0);
55
56        let mut i = 0;
57        let mut index;
58        let mut bucket;
59        while i < 256 {
60            index = Dec::from_usize(i);
61            bucket = Dec::from_u64(self.buckets[i]);
62            sum = sum.add(index.mul(bucket));
63
64            i += 1;
65        }
66
67        sum.div(Dec::from_u64(self.total_buckets))
68    }
69
70    /// get the samples of current state.
71    #[inline(always)]
72    pub const fn samples(&self) -> u64 {
73        self.total_buckets
74    }
75
76    /// oneshot test function for small data.
77    ///
78    /// this is equivalent to `Self::new().update(data).finalize()`.
79    #[inline(always)]
80    pub const fn test(data: &[u8]) -> Dec {
81        let mut this = Self::INIT;
82        this.update(data);
83        this.finalize()
84    }
85}
86
87impl EntropyTest for MeanCalculation {
88    #[inline(always)]
89    fn update(&mut self, bytes: &[u8]) {
90        Self::update(self, bytes);
91    }
92
93    #[inline(always)]
94    fn finalize(&self) -> Dec {
95        Self::finalize(self)
96    }
97}
98