cipher_utils/
lib.rs

1pub mod alphabet;
2pub mod character_set;
3pub mod cipher_type;
4pub mod score;
5
6/// The `frequency` module, providing various utilities relating to frequency analysis.
7pub mod frequency;
8
9use alphabet::Alphabet;
10
11pub trait Analyze {
12    fn index_of_coincidence(&self) -> f64;
13
14    /// Alias for `index_of_coincidence()`.
15    fn ioc(&self) -> f64 {
16        self.index_of_coincidence()
17    }
18
19    /// Returns an `Alphabet` containing the unique characters of this string in-order.
20    fn alphabet(&self) -> Alphabet;
21}
22
23impl<T: AsRef<str>> Analyze for T {
24    fn index_of_coincidence(&self) -> f64 {
25        let mut frequency = [0u32; 26];
26        let mut total_letters = 0;
27
28        for c in self.as_ref().chars() {
29            if c.is_alphabetic() {
30                let idx = c.to_ascii_lowercase() as usize - 'a' as usize;
31                frequency[idx] += 1;
32                total_letters += 1;
33            }
34        }
35
36        if total_letters < 2 {
37            return 0.0;
38        }
39
40        let mut numerator = 0u32;
41
42        for &count in &frequency {
43            numerator += count * (count - 1);
44        }
45
46        let denominator = total_letters * (total_letters - 1);
47
48        numerator as f64 / denominator as f64
49    }
50
51    fn alphabet(&self) -> Alphabet {
52        Alphabet::of_cased(self.as_ref())
53    }
54}