diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Cargo.toml | 9 | ||||
-rw-r--r-- | lib/src/lib.rs | 92 |
2 files changed, 101 insertions, 0 deletions
diff --git a/lib/Cargo.toml b/lib/Cargo.toml new file mode 100644 index 0000000..904ad4d --- /dev/null +++ b/lib/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "base-keysmash" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +fastrand = "2.0" diff --git a/lib/src/lib.rs b/lib/src/lib.rs new file mode 100644 index 0000000..a8d48b6 --- /dev/null +++ b/lib/src/lib.rs @@ -0,0 +1,92 @@ + + +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) { + out.push((decode_sym(pair[0]) << 6) + + (decode_sym(pair[1]) << 4) + + (decode_sym(pair[2]) << 2) + + decode_sym(pair[3])); + } + out +} + +pub fn decode_sym(sym: u8) -> 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)) + .unwrap() +} + + +#[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))); + } + } +} |