summaryrefslogtreecommitdiff
path: root/lib/src/lib.rs
blob: 4f6cad51d81c2bd5dffc95f87220e6bddaf19740 (plain)
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
const HEADERS: [&[u8]; 3] = [b"asd", b"adf", b"ads"];
const HOME_RIGHT: [u8; 4] = [b'a',b's',b'd',b'f'];
const HOME_LEFT: [u8; 4] = [b'h',b'j',b'k',b'l'];
const ABOVE_RIGHT: [u8; 4] = [b'w',b'e',b'r',b't'];
const ABOVE_LEFT: [u8; 4] = [b'u',b'i',b'o',b'p'];

pub fn encode(buf: &[u8]) -> Vec<u8> {
    let mut out = Vec::new();

    let h = HEADERS[fastrand::usize(..HEADERS.len())];
    for s in h {
        out.push(*s);
    }


    for byte in buf {
        let stuff = encode_byte(*byte);
        for b in stuff {
            out.push(b);
        }
    }
    out
}

fn encode_byte(byte: u8) -> [u8; 4] {
    [some_dict()[((byte & 0b11000000) >> 6) as usize],
     some_dict()[((byte & 0b00110000) >> 4) as usize],
     some_dict()[((byte & 0b00001100) >> 2) as usize],
     some_dict()[(byte & 0b00000011) as usize]
    ]
}

fn some_dict() -> &'static [u8; 4] {
    let q = fastrand::usize(0..10);
    if q < 4 {
        return &HOME_RIGHT
    }
    if q < 8 {
        return &HOME_LEFT
    }
    if q < 9 {
        return &ABOVE_RIGHT
    }
    return &ABOVE_LEFT
}

pub fn decode(buf: &[u8]) -> Vec<u8> {
    let buf = &buf[3..];

    let mut out = Vec::new();
    for pair in buf.chunks(4) {
        if pair.len() != 4 {
            continue;
        }

        match (decode_sym(pair[0]), decode_sym(pair[1]), decode_sym(pair[2]), decode_sym(pair[3])) {
            (Some(zero), Some(one), Some(two), Some(three)) => out.push((zero << 6) + (one << 4) + (two << 2) + three),
            (_, _, _, _) => {
                for b in "�".as_bytes() {
                    out.push(*b);
                }
            }
        }
    }
    out
}

pub fn decode_sym(sym: u8) -> Option<u8> {
    let find = |d: &[u8; 4]| -> Option<u8> {
        d.iter().enumerate().find(|s| s.1 == &sym).map(|s| s.0 as u8)
    };
    find(&HOME_RIGHT)
        .or_else(|| find(&HOME_LEFT))
        .or_else(|| find(&ABOVE_RIGHT))
        .or_else(|| find(&ABOVE_LEFT))
}


#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let hello = b"hello, world!";
        assert_eq!(&hello[..], &decode(&encode(hello)));
    }

    #[test]
    fn random() {
        for _ in 0..1000 {
            let mut buf = vec![0; fastrand::usize(..1000)];
            buf.iter_mut().for_each(|s| *s = fastrand::u8(..));
            assert_eq!(&buf[..], &decode(&encode(&buf)));
        }
    }
}