Skip to content

Commit

Permalink
feat(permutate): add mapped permutation
Browse files Browse the repository at this point in the history
Closes #69
  • Loading branch information
JuxhinDB committed Aug 14, 2024
1 parent 3aed9b4 commit bfe782c
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
41 changes: 41 additions & 0 deletions twistrs/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,45 @@ pub static HOMOGLYPHS: phf::Map<char, &'static str> = phf_map! {
'z' => "ʐżźᴢƶẓẕⱬ"
};

pub static MAPPED_VALUES: phf::Map<&'static str, &'static [&'static str]> = phf_map! {
"a" => &["4"],
"b" => &["8", "6"],
"c" => &[],
"d" => &["cl"],
"e" => &["3"],
"f" => &["ph"],
"g" => &["9", "6"],
"h" => &[],
"i" => &["1", "l"],
"j" => &[],
"k" => &[],
"l" => &["1", "i"],
"m" => &["rn", "nn"],
"n" => &[],
"o" => &["0"],
"p" => &[],
"q" => &["9"],
"r" => &[],
"s" => &["5", "z"],
"t" => &["7"],
"u" => &["v"],
"v" => &["u"],
"w" => &["vv"],
"x" => &[],
"y" => &[],
"z" => &["2", "s"],
"0" => &["o"],
"1" => &["i", "l"],
"2" => &["z"],
"3" => &["e"],
"4" => &["a"],
"5" => &["s"],
"6" => &["b", "g"],
"7" => &["t"],
"8" => &["b"],
"9" => &["g", "q"],
"ck" => &["kk"],
"oo" => &["00"],
};

pub static VOWELS: [char; 5] = ['a', 'e', 'i', 'o', 'u'];
41 changes: 40 additions & 1 deletion twistrs/src/permutate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//!
//! Additionally the permutation module can be used independently
//! from the enrichment module.
use crate::constants::{ASCII_LOWER, HOMOGLYPHS, KEYBOARD_LAYOUTS, VOWELS};
use crate::constants::{ASCII_LOWER, HOMOGLYPHS, KEYBOARD_LAYOUTS, MAPPED_VALUES, VOWELS};
use crate::error::Error;

use std::collections::HashSet;
Expand Down Expand Up @@ -67,6 +67,7 @@ pub enum PermutationKind {
Keyword,
Tld,
Homoglyph,
Mapped,
}

#[derive(Clone, thiserror::Error, Debug)]
Expand Down Expand Up @@ -563,6 +564,36 @@ impl Domain {
None
})
}

/// Permutation method that maps one or more characters into another
/// set of one or more characters that are similar, or easy to miss,
/// such as `d` -> `cl`, `ck` -> `kk`.
pub fn mapped(&self) -> impl Iterator<Item = Permutation> + '_ {
let mut results = vec![];

for (key, values) in MAPPED_VALUES.entries() {
if self.domain.contains(key) {
let mut parts = self.domain.split(key);

for mapped_value in *values {
let result = format!(
"{domain}.{tld}",
domain = parts.join(mapped_value),
tld = self.tld
);

if let Ok(domain) = Domain::new(result.as_str()) {
results.push(Permutation {
domain,
kind: PermutationKind::Mapped,
});
}
}
}
}

results.into_iter()
}
}

#[cfg(test)]
Expand Down Expand Up @@ -681,6 +712,14 @@ mod tests {
assert!(!permutations.is_empty());
}

#[test]
fn test_mapping_mode() {
let d = Domain::new("www.exoock96z.com").unwrap();
let permutations: Vec<_> = dbg!(d.mapped().collect());

assert!(!permutations.is_empty());
}

#[test]
fn test_domain_idna_filtering() {
// Examples taken from IDNA Punycode RFC:
Expand Down

0 comments on commit bfe782c

Please sign in to comment.