mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
Add checksum algorithm abstractions
This commit is contained in:
parent
109553436d
commit
9322580967
6 changed files with 77 additions and 102 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<dyn Digest + 'static>, usize
|
|||
"sha256" => ("SHA256", Box::new(Sha256::new()) as Box<dyn Digest>, 256),
|
||||
"sha384" => ("SHA384", Box::new(Sha384::new()) as Box<dyn Digest>, 384),
|
||||
"sha512" => ("SHA512", Box::new(Sha512::new()) as Box<dyn Digest>, 512),
|
||||
"blake2b" => (
|
||||
"BLAKE2",
|
||||
Box::new(blake2b_simd::State::new()) as Box<dyn Digest>,
|
||||
512,
|
||||
),
|
||||
"sm3" => ("SM3", Box::new(sm3::Sm3::new()) as Box<dyn Digest>, 512),
|
||||
"blake2b" => ("BLAKE2", Box::new(Blake2b::new()) as Box<dyn Digest>, 512),
|
||||
"sm3" => ("SM3", Box::new(Sm3::new()) as Box<dyn Digest>, 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!(
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<dyn Digest>, 256),
|
||||
"sha384sum" => ("SHA384", Box::new(Sha384::new()) as Box<dyn Digest>, 384),
|
||||
"sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box<dyn Digest>, 512),
|
||||
"b2sum" => (
|
||||
"BLAKE2",
|
||||
Box::new(blake2b_simd::State::new()) as Box<dyn Digest>,
|
||||
512,
|
||||
),
|
||||
"b3sum" => (
|
||||
"BLAKE3",
|
||||
Box::new(blake3::Hasher::new()) as Box<dyn Digest>,
|
||||
256,
|
||||
),
|
||||
"b2sum" => ("BLAKE2", Box::new(Blake2b::new()) as Box<dyn Digest>, 512),
|
||||
"b3sum" => ("BLAKE3", Box::new(Blake3::new()) as Box<dyn Digest>, 256),
|
||||
"sha3sum" => match matches.get_one::<usize>("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::<usize>("bits") {
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
// spell-checker:ignore memmem
|
||||
// This file is part of the uutils coreutils package.
|
||||
//
|
||||
// (c) Yuan YangHao <yuanyanghau@gmail.com>
|
||||
//
|
||||
// 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 {
|
||||
<Self as sm3::Digest>::new()
|
||||
Self(<sm3::Sm3 as sm3::Digest>::new())
|
||||
}
|
||||
|
||||
fn hash_update(&mut self, input: &[u8]) {
|
||||
self.update(input);
|
||||
<sm3::Sm3 as sm3::Digest>::update(&mut self.0, input);
|
||||
}
|
||||
|
||||
fn hash_finalize(&mut self, out: &mut [u8]) {
|
||||
out.copy_from_slice(&self.clone().finalize());
|
||||
out.copy_from_slice(&<sm3::Sm3 as sm3::Digest>::finalize(self.0.clone()));
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
*self = <Self as sm3::Digest>::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 = <Self as Digest>::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.
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue