crypto_invert/
utils.rs

1use lazy_static::lazy_static;
2use std::collections::BTreeMap;
3
4const LATIN_LOWER0: &str = "abcdefghijklmnopqrstuvwxyz";
5const LATIN_LOWER1: &str = "ɐqɔpǝɟᵷɥᴉfʞꞁɯuodbɹsʇnʌʍxʎz";
6
7const LATIN_UPPER0: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
8const LATIN_UPPER1: &str = "ⱯBƆDƎℲ⅁HIſꞰꞀƜNOԀÒᴚSꞱ∩ɅʍX⅄Z";
9
10const DIGIT0: &str = "0123456789";
11const DIGIT1: &str = "012Ɛᔭ59Ɫ86";
12
13const PUNCTUATION0: &str = ",.;!?&†()[]{}";
14const PUNCTUATION1: &str = "⸲˙⸵¡¿⅋⸸)(][}{";
15
16// const STRING_NORMAL: &str = concat!(LATIN_LOWER0, LATIN_UPPER0, DIGIT0, PUNCTUATION0);
17// const STRING_INVERT: &str = concat!(LATIN_LOWER1, LATIN_UPPER1, DIGIT1, PUNCTUATION1);
18
19lazy_static! {
20    pub static ref MAP_NORMAL: BTreeMap<char, char> = {
21        let normal: String = vec![LATIN_LOWER0, LATIN_UPPER0, DIGIT0, PUNCTUATION0].join("");
22        let invert: String = vec![LATIN_LOWER1, LATIN_UPPER1, DIGIT1, PUNCTUATION1].join("");
23        let mut map = BTreeMap::default();
24        for (i, j) in normal.chars().zip(invert.chars()) {
25            map.insert(i, j);
26        }
27        return map;
28    };
29    pub static ref MAP_INVERT: BTreeMap<char, char> = {
30        let normal: String = vec![LATIN_LOWER0, LATIN_UPPER0, DIGIT0, PUNCTUATION0].join("");
31        let invert: String = vec![LATIN_LOWER1, LATIN_UPPER1, DIGIT1, PUNCTUATION1].join("");
32        let mut map = BTreeMap::default();
33        for (i, j) in invert.chars().zip(normal.chars()) {
34            map.insert(i, j);
35        }
36        return map;
37    };
38}
39
40/// Encodes an ascii string into the invert representation
41///
42/// # Examples
43/// ```rust
44/// use crypto_invert::encode;
45///
46/// let r1 = encode("i love you!");
47/// let r2 = encode("I LOVE YOU!");
48/// assert_eq!(r1, "ᴉ ꞁoʌǝ ʎon¡");
49/// assert_eq!(r2, "I ꞀOɅƎ ⅄O∩¡");
50/// ```
51pub fn encode(input: &str) -> String {
52    let mut out = String::with_capacity(input.len());
53    for c in input.chars() {
54        match MAP_NORMAL.get(&c) {
55            None => out.push(c),
56            Some(s) => out.push(*s),
57        }
58    }
59    return out;
60}
61
62/// Decoding the invert representation to normal string
63///
64/// # Examples
65/// ```rust
66/// use crypto_invert::{decode, encode};
67///
68/// let r1 = "i love you!";
69/// let r2 = "I LOVE YOU!";
70/// assert_eq!(decode(&encode(r1)), r1);
71/// assert_eq!(decode(&encode(r2)), r2);
72/// ```
73pub fn decode(input: &str) -> String {
74    let mut out = String::with_capacity(input.len());
75    for c in input.chars() {
76        match MAP_INVERT.get(&c) {
77            None => out.push(c),
78            Some(s) => out.push(*s),
79        }
80    }
81    return out;
82}