1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
use crate::LeetLevel;
pub(crate) struct LeetReplacementTable{
lookup_table : &'static [&'static str; 26],
}
enum CharOrSlice{
Char(char),
Slice(&'static str)
}
impl LeetReplacementTable {
/// Gets the appropriate leet replacement table for a given leet level.
pub(crate) fn get(leet_level : &LeetLevel) -> LeetReplacementTable {
let lookup_table = match leet_level {
LeetLevel::One => &["4", "b", "c", "d", "3", "f", "g", "h", "i", "j", "k", "1", "m", "n", "0", "p", "9", "r", "s", "7", "u", "v", "w", "x", "y", "z"],
LeetLevel::Two => &["4", "b", "c", "d", "3", "f", "g", "h", "1", "j", "k", "1", "m", "n", "0", "p", "9", "r", "5", "7", "u", "v", "w", "x", "y", "2"],
LeetLevel::Three => &["4", "8", "c", "d", "3", "f", "6", "h", "'", "j", "k", "1", "m", "n", "0", "p", "9", "r", "5", "7", "u", "v", "w", "x", "'/", "2"],
LeetLevel::Four => &["@", "8", "c", "d", "3", "f", "6", "h", "'", "j", "k", "1", "m", "n", "0", "p", "9", "r", "5", "7", "u", "v", "w", "x", "'/", "2"],
LeetLevel::Five => &["@", "|3", "c", "d", "3", "f", "6", "#", "!", "7", "|<", "1", "m", "n", "0", "|>", "9", "|2", "$", "7", "u", "\\/", "w", "x", "'/", "2"],
LeetLevel::Six => &["@", "|3", "c", "|)", "&", "|=", "6", "#", "!", ",|", "|<", "1", "m", "n", "0", "|>", "9", "|2", "$", "7", "u", "\\/", "w", "x", "'/", "2"],
LeetLevel::Seven => &["@", "|3", "[", "|)", "&", "|=", "6", "#", "!", ",|", "|<", "1", "^^", "^/", "0", "|*", "9", "|2", "5", "7", "(_)", "\\/", "\\/\\/", "><", "'/", "2"],
LeetLevel::Eight => &["@", "8", "(", "|)", "&", "|=", "6", "|-|", "!", "_|", "|(", "1", "|\\/|", "|\\|", "()", "|>", "(,)", "|2", "$", "|", "|_|", "\\/", "\\^/", ")(", "'/", "\"/_"],
LeetLevel::Nine => &["@", "8", "(", "|)", "&", "|=", "6", "|-|", "!", "_|", "|{", "|_", "/\\/\\", "|\\|", "()", "|>", "(,)", "|2", "$", "|", "|_|", "\\/", "\\^/", ")(", "'/", "\"/_"],
};
LeetReplacementTable { lookup_table }
}
/// Applies this replacement table to an input string slice.
/// Needs an intermediate allocation.
pub(super) fn leetify(&self, input: &str) -> String{
//PasswordMaker Pro is converting input to lower-case before leet is applied.
//We must apply to_lowercase on the whole input. PasswordMaker Pro is properly treating Final_Sigma, what we cannot do if we just
//iterate on a per-char basis.
input.to_lowercase().chars()
.map(|c| self.conditionally_replace(c))
.fold(String::with_capacity(input.len()), |mut result, c| {
match c {
CharOrSlice::Char(c) => result.push(c),
CharOrSlice::Slice(s) => result.push_str(s),
};
result
})
}
fn conditionally_replace(&self, character : char) -> CharOrSlice {
match (character as usize).checked_sub(0x61).and_then(|index| self.lookup_table.get(index)) {
Some(s) => CharOrSlice::Slice(s),
None => CharOrSlice::Char(character),
}
}
}
#[cfg(test)]
mod leet_tests{
use super::*;
use strum::IntoEnumIterator;
fn get_icelandic_test_string() -> &'static str {
"Kæmi ný Öxi hér, ykist þjófum nú bæði víl og ádrepa." //yes, I know, the upper case Ö is wrong, but it's there to test a property.
}
fn get_icelandic_test_result(level : LeetLevel) -> &'static str {
match level {
LeetLevel::One => "kæmi ný öxi hér, ykis7 þjófum nú bæði ví1 0g ádr3p4.",
LeetLevel::Two => "kæm1 ný öx1 hér, yk157 þjófum nú bæð1 ví1 0g ádr3p4.",
LeetLevel::Three => "kæm' ný öx' hér, '/k'57 þjófum nú 8æð' ví1 06 ádr3p4.",
LeetLevel::Four => "kæm' ný öx' hér, '/k'57 þjófum nú 8æð' ví1 06 ádr3p@.",
LeetLevel::Five => "|<æm! ný öx! #é|2, '/|<!$7 þ7ófum nú |3æð! \\/í1 06 ád|23|>@.",
LeetLevel::Six => "|<æm! ný öx! #é|2, '/|<!$7 þ,|ó|=um nú |3æð! \\/í1 06 á|)|2&|>@.",
LeetLevel::Seven => "|<æ^^! ^/ý ö><! #é|2, '/|<!57 þ,|ó|=(_)^^ ^/ú |3æð! \\/í1 06 á|)|2&|*@.",
LeetLevel::Eight => "|(æ|\\/|! |\\|ý ö)(! |-|é|2, '/|(!$| þ_|ó|=|_||\\/| |\\|ú 8æð! \\/í1 ()6 á|)|2&|>@.",
LeetLevel::Nine => "|{æ/\\/\\! |\\|ý ö)(! |-|é|2, '/|{!$| þ_|ó|=|_|/\\/\\ |\\|ú 8æð! \\/í|_ ()6 á|)|2&|>@.",
}
}
/// Runs a simple icelandic test sentence as found on the web through the leetifier for all levels.
#[test]
fn leet_test_icelandic(){
for leet_level in LeetLevel::iter(){
let result = LeetReplacementTable::get(&leet_level).leetify(get_icelandic_test_string());
let expected = get_icelandic_test_result(leet_level);
assert_eq!(result, expected);
}
}
fn get_greek_test_string() -> &'static str {
"ΕΤΥΜΟΛΟΓΙΚΌ ΛΕΞΙΚΌ ΤΗΣ ΕΛΛΗΝΙΚΉΣ ΓΛΏΣΣΑΣ"
}
fn get_greek_test_result(_level : LeetLevel) -> &'static str {
"ετυμολογικό λεξικό της ελληνικής γλώσσας"
}
#[test]
fn leet_test_greek(){
for leet_level in LeetLevel::iter(){
let result = LeetReplacementTable::get(&leet_level).leetify(get_greek_test_string());
let expected = get_greek_test_result(leet_level);
assert_eq!(result, expected);
}
}
}
|