From 9322580967195a74a91d127fffb0cfb21036c6fc Mon Sep 17 00:00:00 2001 From: Yang Hau Date: Tue, 21 Feb 2023 16:23:18 +0800 Subject: [PATCH] Add checksum algorithm abstractions --- Cargo.lock | 14 ---- src/uu/cksum/Cargo.toml | 8 +-- src/uu/cksum/src/cksum.rs | 19 ++---- src/uu/hashsum/Cargo.toml | 8 --- src/uu/hashsum/src/hashsum.rs | 29 +++------ src/uucore/src/lib/features/sum.rs | 101 +++++++++++++++++------------ 6 files changed, 77 insertions(+), 102 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f08af896a..2d68c19e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2399,14 +2399,8 @@ dependencies = [ name = "uu_cksum" version = "0.0.17" dependencies = [ - "blake2b_simd", - "blake3", "clap", "hex", - "md-5", - "sha1", - "sha2", - "sm3", "uucore", ] @@ -2611,18 +2605,10 @@ dependencies = [ name = "uu_hashsum" version = "0.0.17" dependencies = [ - "blake2b_simd", - "blake3", "clap", - "digest", "hex", - "md-5", "memchr", "regex", - "sha1", - "sha2", - "sha3", - "sm3", "uucore", ] diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index 20406a3f0..9b7f70f8f 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -16,14 +16,8 @@ path = "src/cksum.rs" [dependencies] clap = { workspace=true } -uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["sum"] } +uucore = { workspace=true, features=["sum"] } hex = { workspace=true } -md-5 = { workspace=true } -sha1 = { workspace=true } -sha2 = { workspace=true } -blake2b_simd = { workspace=true } -blake3 = { workspace=true } -sm3 = { workspace=true } [[bin]] name = "cksum" diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index d86c44819..cadf523c2 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -8,9 +8,6 @@ // spell-checker:ignore (ToDO) fname, algo use clap::{crate_version, Arg, Command}; use hex::encode; -use md5::Md5; -use sha1::Sha1; -use sha2::{Sha224, Sha256, Sha384, Sha512}; use std::ffi::OsStr; use std::fs::File; use std::io::{self, stdin, BufReader, Read}; @@ -19,7 +16,10 @@ use std::path::Path; use uucore::{ error::{FromIo, UResult}, format_usage, - sum::{div_ceil, Digest, DigestWriter, BSD, CRC, SYSV}, + sum::{ + div_ceil, Blake2b, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha512, Sm3, + BSD, CRC, SYSV, + }, }; const USAGE: &str = "{} [OPTIONS] [FILE]..."; @@ -36,12 +36,8 @@ fn detect_algo(program: &str) -> (&'static str, Box, usize "sha256" => ("SHA256", Box::new(Sha256::new()) as Box, 256), "sha384" => ("SHA384", Box::new(Sha384::new()) as Box, 384), "sha512" => ("SHA512", Box::new(Sha512::new()) as Box, 512), - "blake2b" => ( - "BLAKE2", - Box::new(blake2b_simd::State::new()) as Box, - 512, - ), - "sm3" => ("SM3", Box::new(sm3::Sm3::new()) as Box, 512), + "blake2b" => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), + "sm3" => ("SM3", Box::new(Sm3::new()) as Box, 512), _ => panic!("unknown algorithm"), } } @@ -81,8 +77,7 @@ where let (sum, sz) = digest_read(&mut options.digest, &mut file, options.output_bits) .map_err_context(|| "failed to read input".to_string())?; - // Refer to GNU sum.c implementation. The BSD checksum output is 5 digit integer - // https://github.com/coreutils/coreutils/blob/master/src/sum.c + // The BSD checksum output is 5 digit integer let bsd_width = 5; match (options.algo_name, not_file) { ("SYSV", true) => println!( diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml index a467dee9f..f335211b8 100644 --- a/src/uu/hashsum/Cargo.toml +++ b/src/uu/hashsum/Cargo.toml @@ -20,14 +20,6 @@ uucore = { workspace=true } memchr = { workspace=true } regex = { workspace=true } hex = { workspace=true } -md-5 = { workspace=true } -sha1 = { workspace=true } -sha2 = { workspace=true } -sha3 = { workspace=true } -blake2b_simd = { workspace=true } -blake3 = { workspace=true } -sm3 = { workspace=true } -digest = { workspace=true } [[bin]] name = "hashsum" diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index a240304be..c49c530e4 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -14,11 +14,7 @@ use clap::crate_version; use clap::ArgAction; use clap::{Arg, ArgMatches, Command}; use hex::encode; -use md5::Md5; use regex::Regex; -use sha1::Sha1; -use sha2::{Sha224, Sha256, Sha384, Sha512}; -use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256}; use std::cmp::Ordering; use std::error::Error; use std::ffi::{OsStr, OsString}; @@ -27,11 +23,12 @@ use std::io::{self, stdin, BufRead, BufReader, Read}; use std::iter; use std::num::ParseIntError; use std::path::Path; -use uucore::crash; -use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult}; -use uucore::show_warning; -use uucore::sum::{Digest, DigestWriter}; +use uucore::sum::{ + Blake2b, Blake3, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha3_224, Sha3_256, + Sha3_384, Sha3_512, Sha512, Shake128, Shake256, +}; +use uucore::{crash, display::Quotable, show_warning}; const NAME: &str = "hashsum"; @@ -64,16 +61,8 @@ fn detect_algo( "sha256sum" => ("SHA256", Box::new(Sha256::new()) as Box, 256), "sha384sum" => ("SHA384", Box::new(Sha384::new()) as Box, 384), "sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box, 512), - "b2sum" => ( - "BLAKE2", - Box::new(blake2b_simd::State::new()) as Box, - 512, - ), - "b3sum" => ( - "BLAKE3", - Box::new(blake3::Hasher::new()) as Box, - 256, - ), + "b2sum" => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), + "b3sum" => ("BLAKE3", Box::new(Blake3::new()) as Box, 256), "sha3sum" => match matches.get_one::("bits") { Some(224) => ( "SHA3-224", @@ -166,10 +155,10 @@ fn detect_algo( set_or_crash("SHA512", Box::new(Sha512::new()), 512); } if matches.get_flag("b2sum") { - set_or_crash("BLAKE2", Box::new(blake2b_simd::State::new()), 512); + set_or_crash("BLAKE2", Box::new(Blake2b::new()), 512); } if matches.get_flag("b3sum") { - set_or_crash("BLAKE3", Box::new(blake3::Hasher::new()), 256); + set_or_crash("BLAKE3", Box::new(Blake3::new()), 256); } if matches.get_flag("sha3") { match matches.get_one::("bits") { diff --git a/src/uucore/src/lib/features/sum.rs b/src/uucore/src/lib/features/sum.rs index c7cec6e09..339414630 100644 --- a/src/uucore/src/lib/features/sum.rs +++ b/src/uucore/src/lib/features/sum.rs @@ -1,4 +1,12 @@ -// spell-checker:ignore memmem +// This file is part of the uutils coreutils package. +// +// (c) Yuan YangHao +// +// For the full copyright and license information, please view the LICENSE file +// that was distributed with this source code. + +// spell-checker:ignore memmem algo + //! Implementations of digest functions, like md5 and sha1. //! //! The [`Digest`] trait represents the interface for providing inputs @@ -30,17 +38,18 @@ pub trait Digest { } } -impl Digest for blake2b_simd::State { +pub struct Blake2b(blake2b_simd::State); +impl Digest for Blake2b { fn new() -> Self { - Self::new() + Self(blake2b_simd::State::new()) } fn hash_update(&mut self, input: &[u8]) { - self.update(input); + self.0.update(input); } fn hash_finalize(&mut self, out: &mut [u8]) { - let hash_result = &self.finalize(); + let hash_result = &self.0.finalize(); out.copy_from_slice(hash_result.as_bytes()); } @@ -53,17 +62,18 @@ impl Digest for blake2b_simd::State { } } -impl Digest for blake3::Hasher { +pub struct Blake3(blake3::Hasher); +impl Digest for Blake3 { fn new() -> Self { - Self::new() + Self(blake3::Hasher::new()) } fn hash_update(&mut self, input: &[u8]) { - self.update(input); + self.0.update(input); } fn hash_finalize(&mut self, out: &mut [u8]) { - let hash_result = &self.finalize(); + let hash_result = &self.0.finalize(); out.copy_from_slice(hash_result.as_bytes()); } @@ -76,23 +86,22 @@ impl Digest for blake3::Hasher { } } -use sm3::{Digest as SM3_D, Sm3}; - +pub struct Sm3(sm3::Sm3); impl Digest for Sm3 { fn new() -> Self { - ::new() + Self(::new()) } fn hash_update(&mut self, input: &[u8]) { - self.update(input); + ::update(&mut self.0, input); } fn hash_finalize(&mut self, out: &mut [u8]) { - out.copy_from_slice(&self.clone().finalize()); + out.copy_from_slice(&::finalize(self.0.clone())); } fn reset(&mut self) { - *self = ::new(); + *self = Self::new(); } fn output_bits(&self) -> usize { @@ -108,7 +117,6 @@ pub struct CRC { size: usize, crc_table: [u32; CRC_TABLE_LEN], } - impl CRC { fn generate_crc_table() -> [u32; CRC_TABLE_LEN] { let mut table = [0; CRC_TABLE_LEN]; @@ -196,7 +204,6 @@ pub fn div_ceil(a: usize, b: usize) -> usize { pub struct BSD { state: u16, } - impl Digest for BSD { fn new() -> Self { Self { state: 0 } @@ -231,7 +238,6 @@ impl Digest for BSD { pub struct SYSV { state: u32, } - impl Digest for SYSV { fn new() -> Self { Self { state: 0 } @@ -266,22 +272,22 @@ impl Digest for SYSV { // Implements the Digest trait for sha2 / sha3 algorithms with fixed output macro_rules! impl_digest_common { - ($type: ty, $size: expr) => { - impl Digest for $type { + ($algo_type: ty, $size: expr) => { + impl Digest for $algo_type { fn new() -> Self { - Self::default() + Self(Default::default()) } fn hash_update(&mut self, input: &[u8]) { - digest::Digest::update(self, input); + digest::Digest::update(&mut self.0, input); } fn hash_finalize(&mut self, out: &mut [u8]) { - digest::Digest::finalize_into_reset(self, out.into()); + digest::Digest::finalize_into_reset(&mut self.0, out.into()); } fn reset(&mut self) { - *self = ::new(); + *self = Self::new(); } fn output_bits(&self) -> usize { @@ -293,18 +299,18 @@ macro_rules! impl_digest_common { // Implements the Digest trait for sha2 / sha3 algorithms with variable output macro_rules! impl_digest_shake { - ($type: ty) => { - impl Digest for $type { + ($algo_type: ty) => { + impl Digest for $algo_type { fn new() -> Self { - Self::default() + Self(Default::default()) } fn hash_update(&mut self, input: &[u8]) { - digest::Update::update(self, input); + digest::Update::update(&mut self.0, input); } fn hash_finalize(&mut self, out: &mut [u8]) { - digest::ExtendableOutputReset::finalize_xof_reset_into(self, out); + digest::ExtendableOutputReset::finalize_xof_reset_into(&mut self.0, out); } fn reset(&mut self) { @@ -318,19 +324,32 @@ macro_rules! impl_digest_shake { }; } -impl_digest_common!(md5::Md5, 128); -impl_digest_common!(sha1::Sha1, 160); -impl_digest_common!(sha2::Sha224, 224); -impl_digest_common!(sha2::Sha256, 256); -impl_digest_common!(sha2::Sha384, 384); -impl_digest_common!(sha2::Sha512, 512); +pub struct Md5(md5::Md5); +pub struct Sha1(sha1::Sha1); +pub struct Sha224(sha2::Sha224); +pub struct Sha256(sha2::Sha256); +pub struct Sha384(sha2::Sha384); +pub struct Sha512(sha2::Sha512); +impl_digest_common!(Md5, 128); +impl_digest_common!(Sha1, 160); +impl_digest_common!(Sha224, 224); +impl_digest_common!(Sha256, 256); +impl_digest_common!(Sha384, 384); +impl_digest_common!(Sha512, 512); -impl_digest_common!(sha3::Sha3_224, 224); -impl_digest_common!(sha3::Sha3_256, 256); -impl_digest_common!(sha3::Sha3_384, 384); -impl_digest_common!(sha3::Sha3_512, 512); -impl_digest_shake!(sha3::Shake128); -impl_digest_shake!(sha3::Shake256); +pub struct Sha3_224(sha3::Sha3_224); +pub struct Sha3_256(sha3::Sha3_256); +pub struct Sha3_384(sha3::Sha3_384); +pub struct Sha3_512(sha3::Sha3_512); +impl_digest_common!(Sha3_224, 224); +impl_digest_common!(Sha3_256, 256); +impl_digest_common!(Sha3_384, 384); +impl_digest_common!(Sha3_512, 512); + +pub struct Shake128(sha3::Shake128); +pub struct Shake256(sha3::Shake256); +impl_digest_shake!(Shake128); +impl_digest_shake!(Shake256); /// A struct that writes to a digest. ///