From 31236c1ee97a1728a1533852e14cc8a838f2fd7e Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 23 Nov 2019 19:57:14 +0800 Subject: [PATCH] add reader fon stdin --- src/main.rs | 123 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 35 deletions(-) diff --git a/src/main.rs b/src/main.rs index cd70834..009aa77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ use rust_util::{ }; use std::{ fs::File, - io::{Read, ErrorKind}, + io::{self, Read, ErrorKind}, }; use crypto::{ digest::Digest, @@ -28,7 +28,7 @@ use indicatif::{ ProgressBar, ProgressStyle }; -use argparse::{ArgumentParser, StoreTrue, Store}; +use argparse::{ArgumentParser, StoreTrue, Store, List}; use libsm::sm3::hash::Sm3Hash; const FILE_SIZE_1GB: u64 = 1024 * 1024 * 1024; @@ -43,7 +43,7 @@ const GIT_HASH: &str = env!("GIT_HASH"); pub struct Options { pub version: bool, pub algorithm: String, - pub file_name: String, + pub file_name_list: Vec, } impl Options { @@ -51,7 +51,7 @@ impl Options { Options { version: false, algorithm: "SHA256".to_string(), - file_name: String::new(), + file_name_list: Vec::new(), } } @@ -61,7 +61,7 @@ impl Options { ap.set_description("digest - command line digest tool."); ap.refer(&mut self.algorithm).add_option(&["-a", "--algorithm"], Store, "Algorithm, e.g. SHA256, SM3"); ap.refer(&mut self.version).add_option(&["-v", "--version"], StoreTrue, "Print version"); - ap.refer(&mut self.file_name).add_argument("FILE NAME", Store, "Search text"); + ap.refer(&mut self.file_name_list).add_argument("File names", List, "File names to be digested"); ap.parse_args_or_exit(); } @@ -83,36 +83,57 @@ fn main() -> XResult<()> { return Ok(()); } - if options.file_name == "" { - println!("NO FILE NAME!"); - return Ok(()); - } - - let the_fn = options.file_name.as_str(); let the_algo = options.algorithm.to_uppercase(); - - match the_algo.as_str() { - "MD5" => println!("{} - {} ({})", calc_file_digest(&mut Md5::new(), the_fn)?, the_fn, the_algo), - "SHA1" | "SHA-1" => println!("{} - {} ({})", calc_file_digest(&mut Sha1::new(), the_fn)?, the_fn, the_algo), - "SHA224" | "SHA-224" => println!("{} - {} ({})", calc_file_digest(&mut Sha224::new(), the_fn)?, the_fn, the_algo), - "SHA256" | "SHA-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha256::new(), the_fn)?, the_fn, the_algo), - "SHA384" | "SHA-384" => println!("{} - {} ({})", calc_file_digest(&mut Sha384::new(), the_fn)?, the_fn, the_algo), - "SHA512" | "SHA-512" => println!("{} - {} ({})", calc_file_digest(&mut Sha512::new(), the_fn)?, the_fn, the_algo), - "SHA512-224" => println!("{} - {} ({})", calc_file_digest(&mut Sha512Trunc224::new(), the_fn)?, the_fn, the_algo), - "SHA512-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha512Trunc256::new(), the_fn)?, the_fn, the_algo), - "SHA3-224" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::sha3_224(), the_fn)?, the_fn, the_algo), - "SHA3-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::sha3_256(), the_fn)?, the_fn, the_algo), - "SHA3-384" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::sha3_384(), the_fn)?, the_fn, the_algo), - "SHA3-512" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::sha3_512(), the_fn)?, the_fn, the_algo), - "SHAKE-128" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::shake_128(), the_fn)?, the_fn, the_algo), - "SHAKE-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::shake_256(), the_fn)?, the_fn, the_algo), - "KECCAK-224" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::keccak224(), the_fn)?, the_fn, the_algo), - "KECCAK-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::keccak256(), the_fn)?, the_fn, the_algo), - "KECCAK-384" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::keccak384(), the_fn)?, the_fn, the_algo), - "KECCAK-512" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::keccak512(), the_fn)?, the_fn, the_algo), - "SM3" => println!("{} - {} ({})", hex::encode(Sm3Hash::new(&read_file_full(the_fn)?).get_hash()), the_fn, the_algo), - _ => print_message(MessageType::ERROR, &format!("Unknown algorithm: {}", options.algorithm)), - }; + if options.file_name_list.is_empty() { + match the_algo.as_str() { + "MD5" => println!("{} - ({})", calc_digest_stdin(&mut Md5::new())?, the_algo), + "SHA1" | "SHA-1" => println!("{} - ({})", calc_digest_stdin(&mut Sha1::new())?, the_algo), + "SHA224" | "SHA-224" => println!("{} - ({})", calc_digest_stdin(&mut Sha224::new())?, the_algo), + "SHA256" | "SHA-256" => println!("{} - ({})", calc_digest_stdin(&mut Sha256::new())?, the_algo), + "SHA384" | "SHA-384" => println!("{} - ({})", calc_digest_stdin(&mut Sha384::new())?, the_algo), + "SHA512" | "SHA-512" => println!("{} - ({})", calc_digest_stdin(&mut Sha512::new())?, the_algo), + "SHA512-224" => println!("{} - ({})", calc_digest_stdin(&mut Sha512Trunc224::new())?, the_algo), + "SHA512-256" => println!("{} - ({})", calc_digest_stdin(&mut Sha512Trunc256::new())?, the_algo), + "SHA3-224" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::sha3_224())?, the_algo), + "SHA3-256" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::sha3_256())?, the_algo), + "SHA3-384" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::sha3_384())?, the_algo), + "SHA3-512" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::sha3_512())?, the_algo), + "SHAKE-128" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::shake_128())?, the_algo), + "SHAKE-256" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::shake_256())?, the_algo), + "KECCAK-224" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::keccak224())?, the_algo), + "KECCAK-256" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::keccak256())?, the_algo), + "KECCAK-384" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::keccak384())?, the_algo), + "KECCAK-512" => println!("{} - ({})", calc_digest_stdin(&mut Sha3::keccak512())?, the_algo), + "SM3" => println!("{} - ({})", hex::encode(Sm3Hash::new(&read_full_stdin()?).get_hash()), the_algo), + _ => print_message(MessageType::ERROR, &format!("Unknown algorithm: {}", options.algorithm)), + }; + } else { + for f in options.file_name_list { + let the_fn = f.as_str(); + match the_algo.as_str() { + "MD5" => println!("{} - {} ({})", calc_file_digest(&mut Md5::new(), the_fn)?, the_fn, the_algo), + "SHA1" | "SHA-1" => println!("{} - {} ({})", calc_file_digest(&mut Sha1::new(), the_fn)?, the_fn, the_algo), + "SHA224" | "SHA-224" => println!("{} - {} ({})", calc_file_digest(&mut Sha224::new(), the_fn)?, the_fn, the_algo), + "SHA256" | "SHA-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha256::new(), the_fn)?, the_fn, the_algo), + "SHA384" | "SHA-384" => println!("{} - {} ({})", calc_file_digest(&mut Sha384::new(), the_fn)?, the_fn, the_algo), + "SHA512" | "SHA-512" => println!("{} - {} ({})", calc_file_digest(&mut Sha512::new(), the_fn)?, the_fn, the_algo), + "SHA512-224" => println!("{} - {} ({})", calc_file_digest(&mut Sha512Trunc224::new(), the_fn)?, the_fn, the_algo), + "SHA512-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha512Trunc256::new(), the_fn)?, the_fn, the_algo), + "SHA3-224" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::sha3_224(), the_fn)?, the_fn, the_algo), + "SHA3-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::sha3_256(), the_fn)?, the_fn, the_algo), + "SHA3-384" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::sha3_384(), the_fn)?, the_fn, the_algo), + "SHA3-512" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::sha3_512(), the_fn)?, the_fn, the_algo), + "SHAKE-128" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::shake_128(), the_fn)?, the_fn, the_algo), + "SHAKE-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::shake_256(), the_fn)?, the_fn, the_algo), + "KECCAK-224" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::keccak224(), the_fn)?, the_fn, the_algo), + "KECCAK-256" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::keccak256(), the_fn)?, the_fn, the_algo), + "KECCAK-384" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::keccak384(), the_fn)?, the_fn, the_algo), + "KECCAK-512" => println!("{} - {} ({})", calc_file_digest(&mut Sha3::keccak512(), the_fn)?, the_fn, the_algo), + "SM3" => println!("{} - {} ({})", hex::encode(Sm3Hash::new(&read_file_full(the_fn)?).get_hash()), the_fn, the_algo), + _ => print_message(MessageType::ERROR, &format!("Unknown algorithm: {}", options.algorithm)), + }; + } + } Ok(()) } @@ -172,10 +193,42 @@ fn calc_file_digest(digest: &mut dyn Digest, file_name: &str) -> XResult Ok(0) => { pb.finish_and_clear(); return Ok(digest.result_str()); }, Ok(len) => len, Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, - Err(e) => return Err(Box::new(e)), + Err(e) => return Ok(format!("ERROR: {}", e)),//Err(Box::new(e)), }; digest.input(&buf[..len]); processed += len as u64; pb.set_position(processed); } } + + +fn read_full_stdin() -> XResult> { + let mut buf: [u8; BUFF_SIZE] = [0u8; BUFF_SIZE]; + let mut ret: Vec = Vec::new(); + let stdin = io::stdin(); + let mut handle = stdin.lock(); + loop { + let len = match handle.read(&mut buf) { + Ok(0) => { return Ok(ret); }, + Ok(len) => len, + Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, + Err(e) => return Err(Box::new(e)), + }; + ret.append(&mut buf[..len].to_vec()); + } +} + +fn calc_digest_stdin(digest: &mut dyn Digest) -> XResult { + let mut buf: [u8; BUFF_SIZE] = [0u8; BUFF_SIZE]; + let stdin = io::stdin(); + let mut handle = stdin.lock(); + loop { + let len = match handle.read(&mut buf) { + Ok(0) => { return Ok(digest.result_str()); }, + Ok(len) => len, + Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, + Err(e) => return Err(Box::new(e)), + }; + digest.input(&buf[..len]); + } +}