1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #7169 from RenjiSann/cksum-9.6-fixes

cksum: add CRC32B algorithm added in GNU 9.6
This commit is contained in:
Sylvestre Ledru 2025-01-20 15:19:49 +01:00 committed by GitHub
commit 3513ee66c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 78 additions and 13 deletions

1
Cargo.lock generated
View file

@ -3461,6 +3461,7 @@ dependencies = [
"blake2b_simd", "blake2b_simd",
"blake3", "blake3",
"clap", "clap",
"crc32fast",
"data-encoding", "data-encoding",
"data-encoding-macro", "data-encoding-macro",
"digest", "digest",

View file

@ -356,6 +356,7 @@ sha3 = "0.10.8"
blake2b_simd = "1.0.2" blake2b_simd = "1.0.2"
blake3 = "1.5.1" blake3 = "1.5.1"
sm3 = "0.4.2" sm3 = "0.4.2"
crc32fast = "1.4.2"
digest = "0.10.7" digest = "0.10.7"
uucore = { version = "0.0.29", package = "uucore", path = "src/uucore" } uucore = { version = "0.0.29", package = "uucore", path = "src/uucore" }

View file

@ -13,6 +13,7 @@ DIGEST determines the digest algorithm and default output format:
- `sysv`: (equivalent to sum -s) - `sysv`: (equivalent to sum -s)
- `bsd`: (equivalent to sum -r) - `bsd`: (equivalent to sum -r)
- `crc`: (equivalent to cksum) - `crc`: (equivalent to cksum)
- `crc32b`: (only available through cksum)
- `md5`: (equivalent to md5sum) - `md5`: (equivalent to md5sum)
- `sha1`: (equivalent to sha1sum) - `sha1`: (equivalent to sha1sum)
- `sha224`: (equivalent to sha224sum) - `sha224`: (equivalent to sha224sum)

View file

@ -14,7 +14,7 @@ use std::path::Path;
use uucore::checksum::{ use uucore::checksum::{
calculate_blake2b_length, detect_algo, digest_reader, perform_checksum_validation, calculate_blake2b_length, detect_algo, digest_reader, perform_checksum_validation,
ChecksumError, ChecksumOptions, ALGORITHM_OPTIONS_BLAKE2B, ALGORITHM_OPTIONS_BSD, ChecksumError, ChecksumOptions, ALGORITHM_OPTIONS_BLAKE2B, ALGORITHM_OPTIONS_BSD,
ALGORITHM_OPTIONS_CRC, ALGORITHM_OPTIONS_SYSV, SUPPORTED_ALGORITHMS, ALGORITHM_OPTIONS_CRC, ALGORITHM_OPTIONS_CRC32B, ALGORITHM_OPTIONS_SYSV, SUPPORTED_ALGORITHMS,
}; };
use uucore::{ use uucore::{
encoding, encoding,
@ -113,7 +113,10 @@ where
} }
OutputFormat::Hexadecimal => sum_hex, OutputFormat::Hexadecimal => sum_hex,
OutputFormat::Base64 => match options.algo_name { OutputFormat::Base64 => match options.algo_name {
ALGORITHM_OPTIONS_CRC | ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => sum_hex, ALGORITHM_OPTIONS_CRC
| ALGORITHM_OPTIONS_CRC32B
| ALGORITHM_OPTIONS_SYSV
| ALGORITHM_OPTIONS_BSD => sum_hex,
_ => encoding::for_cksum::BASE64.encode(&hex::decode(sum_hex).unwrap()), _ => encoding::for_cksum::BASE64.encode(&hex::decode(sum_hex).unwrap()),
}, },
}; };
@ -140,7 +143,7 @@ where
!not_file, !not_file,
String::new(), String::new(),
), ),
ALGORITHM_OPTIONS_CRC => ( ALGORITHM_OPTIONS_CRC | ALGORITHM_OPTIONS_CRC32B => (
format!("{sum} {sz}{}", if not_file { "" } else { " " }), format!("{sum} {sz}{}", if not_file { "" } else { " " }),
!not_file, !not_file,
String::new(), String::new(),
@ -289,7 +292,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
None => None, None => None,
}; };
if ["bsd", "crc", "sysv"].contains(&algo_name) && check { if ["bsd", "crc", "sysv", "crc32b"].contains(&algo_name) && check {
return Err(ChecksumError::AlgorithmNotSupportedWithCheck.into()); return Err(ChecksumError::AlgorithmNotSupportedWithCheck.into());
} }

View file

@ -52,6 +52,7 @@ sha3 = { workspace = true, optional = true }
blake2b_simd = { workspace = true, optional = true } blake2b_simd = { workspace = true, optional = true }
blake3 = { workspace = true, optional = true } blake3 = { workspace = true, optional = true }
sm3 = { workspace = true, optional = true } sm3 = { workspace = true, optional = true }
crc32fast = { workspace = true, optional = true }
regex = { workspace = true, optional = true } regex = { workspace = true, optional = true }
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
@ -106,6 +107,7 @@ sum = [
"blake2b_simd", "blake2b_simd",
"blake3", "blake3",
"sm3", "sm3",
"crc32fast",
] ]
update-control = [] update-control = []
utf8 = [] utf8 = []

View file

@ -23,7 +23,7 @@ use crate::{
os_str_as_bytes, os_str_from_bytes, read_os_string_lines, show, show_error, show_warning_caps, os_str_as_bytes, os_str_from_bytes, read_os_string_lines, show, show_error, show_warning_caps,
sum::{ sum::{
Blake2b, Blake3, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha3_224, Blake2b, Blake3, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha3_224,
Sha3_256, Sha3_384, Sha3_512, Sha512, Shake128, Shake256, Sm3, BSD, CRC, SYSV, Sha3_256, Sha3_384, Sha3_512, Sha512, Shake128, Shake256, Sm3, BSD, CRC, CRC32B, SYSV,
}, },
util_name, util_name,
}; };
@ -32,6 +32,7 @@ use thiserror::Error;
pub const ALGORITHM_OPTIONS_SYSV: &str = "sysv"; pub const ALGORITHM_OPTIONS_SYSV: &str = "sysv";
pub const ALGORITHM_OPTIONS_BSD: &str = "bsd"; pub const ALGORITHM_OPTIONS_BSD: &str = "bsd";
pub const ALGORITHM_OPTIONS_CRC: &str = "crc"; pub const ALGORITHM_OPTIONS_CRC: &str = "crc";
pub const ALGORITHM_OPTIONS_CRC32B: &str = "crc32b";
pub const ALGORITHM_OPTIONS_MD5: &str = "md5"; pub const ALGORITHM_OPTIONS_MD5: &str = "md5";
pub const ALGORITHM_OPTIONS_SHA1: &str = "sha1"; pub const ALGORITHM_OPTIONS_SHA1: &str = "sha1";
pub const ALGORITHM_OPTIONS_SHA3: &str = "sha3"; pub const ALGORITHM_OPTIONS_SHA3: &str = "sha3";
@ -46,10 +47,11 @@ pub const ALGORITHM_OPTIONS_SM3: &str = "sm3";
pub const ALGORITHM_OPTIONS_SHAKE128: &str = "shake128"; pub const ALGORITHM_OPTIONS_SHAKE128: &str = "shake128";
pub const ALGORITHM_OPTIONS_SHAKE256: &str = "shake256"; pub const ALGORITHM_OPTIONS_SHAKE256: &str = "shake256";
pub const SUPPORTED_ALGORITHMS: [&str; 15] = [ pub const SUPPORTED_ALGORITHMS: [&str; 16] = [
ALGORITHM_OPTIONS_SYSV, ALGORITHM_OPTIONS_SYSV,
ALGORITHM_OPTIONS_BSD, ALGORITHM_OPTIONS_BSD,
ALGORITHM_OPTIONS_CRC, ALGORITHM_OPTIONS_CRC,
ALGORITHM_OPTIONS_CRC32B,
ALGORITHM_OPTIONS_MD5, ALGORITHM_OPTIONS_MD5,
ALGORITHM_OPTIONS_SHA1, ALGORITHM_OPTIONS_SHA1,
ALGORITHM_OPTIONS_SHA3, ALGORITHM_OPTIONS_SHA3,
@ -183,7 +185,7 @@ pub enum ChecksumError {
LengthOnlyForBlake2b, LengthOnlyForBlake2b,
#[error("the --binary and --text options are meaningless when verifying checksums")] #[error("the --binary and --text options are meaningless when verifying checksums")]
BinaryTextConflict, BinaryTextConflict,
#[error("--check is not supported with --algorithm={{bsd,sysv,crc}}")] #[error("--check is not supported with --algorithm={{bsd,sysv,crc,crc32b}}")]
AlgorithmNotSupportedWithCheck, AlgorithmNotSupportedWithCheck,
#[error("You cannot combine multiple hash algorithms!")] #[error("You cannot combine multiple hash algorithms!")]
CombineMultipleAlgorithms, CombineMultipleAlgorithms,
@ -334,6 +336,11 @@ pub fn detect_algo(algo: &str, length: Option<usize>) -> UResult<HashAlgorithm>
create_fn: Box::new(|| Box::new(CRC::new())), create_fn: Box::new(|| Box::new(CRC::new())),
bits: 256, bits: 256,
}), }),
ALGORITHM_OPTIONS_CRC32B => Ok(HashAlgorithm {
name: ALGORITHM_OPTIONS_CRC32B,
create_fn: Box::new(|| Box::new(CRC32B::new())),
bits: 32,
}),
ALGORITHM_OPTIONS_MD5 | "md5sum" => Ok(HashAlgorithm { ALGORITHM_OPTIONS_MD5 | "md5sum" => Ok(HashAlgorithm {
name: ALGORITHM_OPTIONS_MD5, name: ALGORITHM_OPTIONS_MD5,
create_fn: Box::new(|| Box::new(Md5::new())), create_fn: Box::new(|| Box::new(Md5::new())),

View file

@ -207,6 +207,37 @@ impl Digest for CRC {
} }
} }
pub struct CRC32B(crc32fast::Hasher);
impl Digest for CRC32B {
fn new() -> Self {
Self(crc32fast::Hasher::new())
}
fn hash_update(&mut self, input: &[u8]) {
self.0.update(input);
}
fn hash_finalize(&mut self, out: &mut [u8]) {
let result = self.0.clone().finalize();
let slice = result.to_be_bytes();
out.copy_from_slice(&slice);
}
fn reset(&mut self) {
self.0.reset();
}
fn output_bits(&self) -> usize {
32
}
fn result_str(&mut self) -> String {
let mut out = [0; 4];
self.hash_finalize(&mut out);
format!("{}", u32::from_be_bytes(out))
}
}
pub struct BSD { pub struct BSD {
state: u16, state: u16,
} }

View file

@ -301,7 +301,7 @@ fn test_check_algo() {
.arg("lorem_ipsum.txt") .arg("lorem_ipsum.txt")
.fails() .fails()
.no_stdout() .no_stdout()
.stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc}") .stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc,crc32b}")
.code_is(1); .code_is(1);
new_ucmd!() new_ucmd!()
.arg("-a=sysv") .arg("-a=sysv")
@ -309,7 +309,7 @@ fn test_check_algo() {
.arg("lorem_ipsum.txt") .arg("lorem_ipsum.txt")
.fails() .fails()
.no_stdout() .no_stdout()
.stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc}") .stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc,crc32b}")
.code_is(1); .code_is(1);
new_ucmd!() new_ucmd!()
.arg("-a=crc") .arg("-a=crc")
@ -317,7 +317,15 @@ fn test_check_algo() {
.arg("lorem_ipsum.txt") .arg("lorem_ipsum.txt")
.fails() .fails()
.no_stdout() .no_stdout()
.stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc}") .stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc,crc32b}")
.code_is(1);
new_ucmd!()
.arg("-a=crc32b")
.arg("--check")
.arg("lorem_ipsum.txt")
.fails()
.no_stdout()
.stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc,crc32b}")
.code_is(1); .code_is(1);
} }
@ -1661,10 +1669,11 @@ mod gnu_cksum_base64 {
use super::*; use super::*;
use crate::common::util::log_info; use crate::common::util::log_info;
const PAIRS: [(&str, &str); 11] = [ const PAIRS: [(&str, &str); 12] = [
("sysv", "0 0 f"), ("sysv", "0 0 f"),
("bsd", "00000 0 f"), ("bsd", "00000 0 f"),
("crc", "4294967295 0 f"), ("crc", "4294967295 0 f"),
("crc32b", "0 0 f"),
("md5", "1B2M2Y8AsgTpgAmY7PhCfg=="), ("md5", "1B2M2Y8AsgTpgAmY7PhCfg=="),
("sha1", "2jmj7l5rSw0yVb/vlWAYkK/YBwk="), ("sha1", "2jmj7l5rSw0yVb/vlWAYkK/YBwk="),
("sha224", "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw=="), ("sha224", "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw=="),
@ -1693,7 +1702,7 @@ mod gnu_cksum_base64 {
} }
fn output_format(algo: &str, digest: &str) -> String { fn output_format(algo: &str, digest: &str) -> String {
if ["sysv", "bsd", "crc"].contains(&algo) { if ["sysv", "bsd", "crc", "crc32b"].contains(&algo) {
digest.to_string() digest.to_string()
} else { } else {
format!("{} (f) = {}", algo.to_uppercase(), digest).replace("BLAKE2B", "BLAKE2b") format!("{} (f) = {}", algo.to_uppercase(), digest).replace("BLAKE2B", "BLAKE2b")
@ -1706,6 +1715,7 @@ mod gnu_cksum_base64 {
let scene = make_scene(); let scene = make_scene();
for (algo, digest) in PAIRS { for (algo, digest) in PAIRS {
log_info("ALGORITHM", algo);
scene scene
.ucmd() .ucmd()
.arg("--base64") .arg("--base64")
@ -1724,8 +1734,17 @@ mod gnu_cksum_base64 {
let scene = make_scene(); let scene = make_scene();
for (algo, digest) in PAIRS { for (algo, digest) in PAIRS {
if ["sysv", "bsd", "crc"].contains(&algo) { if ["sysv", "bsd", "crc", "crc32b"].contains(&algo) {
// These algorithms do not accept `--check` // These algorithms do not accept `--check`
scene
.ucmd()
.arg("--check")
.arg("-a")
.arg(algo)
.fails()
.stderr_only(
"cksum: --check is not supported with --algorithm={bsd,sysv,crc,crc32b}\n",
);
continue; continue;
} }