diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.lock | 237 | ||||
-rw-r--r-- | Cargo.toml | 7 | ||||
-rw-r--r-- | Readme.md | 11 | ||||
-rw-r--r-- | cli/Cargo.toml | 10 | ||||
-rw-r--r-- | cli/src/main.rs | 28 | ||||
-rw-r--r-- | lib/Cargo.toml | 9 | ||||
-rw-r--r-- | lib/src/lib.rs | 92 |
8 files changed, 395 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..fd1d55f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,237 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "base-keysmash" +version = "0.1.0" +dependencies = [ + "fastrand", +] + +[[package]] +name = "base-keysmash-cli" +version = "0.1.0" +dependencies = [ + "base-keysmash", + "clap", +] + +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "proc-macro2" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "2.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..66de164 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] + +resolver = "2" +members = [ + "lib", + "cli" +] diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..73e9a24 --- /dev/null +++ b/Readme.md @@ -0,0 +1,11 @@ +# base-keysmash + +the implementation is sloppy and cursed, but honestly, what did you expect? + +~~~shell +> echo "you're cute!" > base_keysmash +adfsfkeidlfjljshdeljthoskishdhhjdhljlssstsasksjhkhihakk +~~~ + +With thanks to [May's talk at emf 2022](https://media.ccc.de/v/emf2022-237-asdkfldsalkasdf-keysmashes-sexuality) +and Gretchen McCulloch's *Because Internet: Understanding the New Rules of Language*. diff --git a/cli/Cargo.toml b/cli/Cargo.toml new file mode 100644 index 0000000..8ab1a10 --- /dev/null +++ b/cli/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "base-keysmash-cli" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +base-keysmash = { path = "../lib" } +clap = { version = "4.4", features = [ "derive" ] } diff --git a/cli/src/main.rs b/cli/src/main.rs new file mode 100644 index 0000000..77c56de --- /dev/null +++ b/cli/src/main.rs @@ -0,0 +1,28 @@ + +use clap::Parser; +use std::io::BufRead; +use std::io::Write; + +#[derive(Parser, Debug)] +struct Args { + #[arg(short)] + decode: bool +} + + +fn main() { + let args = Args::parse(); + + let mut stdin = std::io::stdin().lock(); + let mut input = Vec::new(); + stdin.read_until(0, &mut input).unwrap(); + + let output = if args.decode { + let input = input.into_iter().filter(|s| s.is_ascii() && !s.is_ascii_whitespace()).collect::<Vec<u8>>(); + base_keysmash::decode(&input[..]) + } else { + base_keysmash::encode(&input) + }; + + std::io::stdout().lock().write_all(&output).unwrap(); +} 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))); + } + } +} |