commit 0b863120e6e4e0d88c6bc26e734ce632998c8106 Author: _ <_@_> Date: Sat Jan 7 12:53:19 2023 -0600 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..350f73e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/untracked diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..3e6fd80 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,153 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "blake3" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cc" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "constant_time_eq" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "expectocat" +version = "0.1.0" +dependencies = [ + "anyhow", + "blake3", + "hex", + "sha2", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..865cb72 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "expectocat" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.68" +blake3 = "1.3.3" +hex = "0.4.3" +sha2 = "0.10.6" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..f5d7503 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,91 @@ +use std::{ + env, + io::{ + self, + Read, + Write, + }, +}; + +use anyhow::{ + Result, + bail, +}; + +use sha2::Digest; + +fn main () -> Result <()> { + let mut opts = parse_opts (env::args ())?; + + let mut stdin = io::stdin ().lock (); + let mut stdout = io::stdout ().lock (); + + let buffer_size = 512 * 1_024; + + loop { + let mut buf = vec! [0u8; buffer_size]; + + let bytes_read = stdin.read (&mut buf)?; + if bytes_read == 0 { + break; + } + let buf = &buf [0..bytes_read]; + + if let Some ((h, _)) = opts.sha384.as_mut () { + h.update (buf); + } + if let Some ((h, _)) = opts.blake3.as_mut () { + h.update (buf); + } + + stdout.write_all (&buf)?; + } + + if let Some ((h, expected)) = opts.sha384 { + let actual = hex::encode (h.finalize ()); + if expected != actual { + bail! ("SHA384 doesn't match. Expected {}, actual {}", expected, actual); + } + } + + if let Some ((h, expected)) = opts.blake3 { + let actual = h.finalize (); + if expected != actual { + bail! ("BLAKE3 doesn't match. Expected {:?}, actual {:?}", expected, actual); + } + } + + Ok (()) +} + +#[derive (Default)] +struct Opts { + blake3: Option <(blake3::Hasher, blake3::Hash)>, + sha384: Option <(sha2::Sha384, String)>, +} + +fn parse_opts > (mut args: I) +-> Result +{ + let mut opts = Opts::default (); + + loop { + let arg = match args.next () { + None => return Ok (opts), + Some (x) => x, + }; + + if arg == "--blake3" { + match args.next () { + None => bail! ("Missing argument for --blake3"), + Some (x) => opts.blake3 = Some ((blake3::Hasher::new (), blake3::Hash::from_hex (x)?)), + } + } + else if arg == "--sha384" { + match args.next () { + None => bail! ("Missing argument for --sha384"), + Some (x) => opts.sha384 = Some ((sha2::Sha384::new (), x)), + } + } + } +}