ctf_brute/ops/
pattern.rs

1use std::ops::RangeInclusive;
2
3pub mod iter;
4mod parser;
5
6use super::{bruterange::BruteRangeIter, mbruterange::MBruteRangeIter, BruteRange, MBruteRange};
7
8#[derive(Clone, Debug)]
9pub enum Pattern {
10    //TODO: Send read only references
11    Range(BruteRange),
12    MRange(MBruteRange),
13    Empty(),
14    Group(Vec<Pattern>),
15    Length(Box<Pattern>, RangeInclusive<u32>),
16}
17
18#[derive(Clone, Debug)]
19pub enum PatternIter {
20    Range(BruteRangeIter),
21    MRange(MBruteRangeIter),
22    Empty(bool),
23    Group(Vec<Pattern>, Vec<PatternIter>, Vec<Option<String>>),
24    Length(Vec<PatternIter>), //Flatten<Map<RangeInclusive<u32>, Fn>>)
25}
26
27impl Pattern {
28    pub fn from_pattern(pattern: &str) -> Option<Pattern> {
29        parser::parse_pattern(pattern)
30    }
31
32    pub fn len(&self) -> Option<u128> {
33        match &self {
34            Self::Range(range) => Some(range.len() as u128),
35            Self::MRange(range) => Some(range.len() as u128),
36            Self::Group(patterns) => patterns
37                .iter()
38                .fold(Some(1u128), |b, x| x.len()?.checked_mul(b?)),
39            Self::Empty() => Some(1u128),
40            Self::Length(pattern, range) => {
41                let mut range = range.clone();
42                let pattern_len = pattern.len()?;
43                let first = range.next()?;
44                let mut sum = pattern_len.checked_pow(first)?;
45                let mut pow = sum;
46                for _ in range {
47                    pow = pow.checked_mul(pattern_len as u128)?;
48                    sum = sum.checked_add(pow)?;
49                }
50                Some(sum)
51            }
52        }
53    }
54}