Skip to content

Commit

Permalink
cksum: Add crc32b algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
RenjiSann committed Jan 20, 2025
1 parent 9f07d50 commit f89eb8b
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ sha3 = "0.10.8"
blake2b_simd = "1.0.2"
blake3 = "1.5.1"
sm3 = "0.4.2"
crc32fast = "1.4.2"
digest = "0.10.7"

uucore = { version = "0.0.29", package = "uucore", path = "src/uucore" }
Expand Down
1 change: 1 addition & 0 deletions src/uu/cksum/cksum.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ DIGEST determines the digest algorithm and default output format:
- `sysv`: (equivalent to sum -s)
- `bsd`: (equivalent to sum -r)
- `crc`: (equivalent to cksum)
- `crc32b`: (only available through cksum)
- `md5`: (equivalent to md5sum)
- `sha1`: (equivalent to sha1sum)
- `sha224`: (equivalent to sha224sum)
Expand Down
11 changes: 7 additions & 4 deletions src/uu/cksum/src/cksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::path::Path;
use uucore::checksum::{
calculate_blake2b_length, detect_algo, digest_reader, perform_checksum_validation,
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::{
encoding,
Expand Down Expand Up @@ -113,7 +113,10 @@ where
}
OutputFormat::Hexadecimal => sum_hex,
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()),
},
};
Expand All @@ -140,7 +143,7 @@ where
!not_file,
String::new(),
),
ALGORITHM_OPTIONS_CRC => (
ALGORITHM_OPTIONS_CRC | ALGORITHM_OPTIONS_CRC32B => (
format!("{sum} {sz}{}", if not_file { "" } else { " " }),
!not_file,
String::new(),
Expand Down Expand Up @@ -289,7 +292,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
None => None,
};

if ["bsd", "crc", "sysv"].contains(&algo_name) && check {
if ["bsd", "crc", "sysv", "crc32b"].contains(&algo_name) && check {
return Err(ChecksumError::AlgorithmNotSupportedWithCheck.into());
}

Expand Down
2 changes: 2 additions & 0 deletions src/uucore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ sha3 = { workspace = true, optional = true }
blake2b_simd = { workspace = true, optional = true }
blake3 = { workspace = true, optional = true }
sm3 = { workspace = true, optional = true }
crc32fast = {workspace = true, optional = true}
regex = { workspace = true, optional = true }

[target.'cfg(unix)'.dependencies]
Expand Down Expand Up @@ -106,6 +107,7 @@ sum = [
"blake2b_simd",
"blake3",
"sm3",
"crc32fast",
]
update-control = []
utf8 = []
Expand Down
13 changes: 10 additions & 3 deletions src/uucore/src/lib/features/checksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
os_str_as_bytes, os_str_from_bytes, read_os_string_lines, show, show_error, show_warning_caps,
sum::{
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,
};
Expand All @@ -32,6 +32,7 @@ use thiserror::Error;
pub const ALGORITHM_OPTIONS_SYSV: &str = "sysv";
pub const ALGORITHM_OPTIONS_BSD: &str = "bsd";
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_SHA1: &str = "sha1";
pub const ALGORITHM_OPTIONS_SHA3: &str = "sha3";
Expand All @@ -46,10 +47,11 @@ pub const ALGORITHM_OPTIONS_SM3: &str = "sm3";
pub const ALGORITHM_OPTIONS_SHAKE128: &str = "shake128";
pub const ALGORITHM_OPTIONS_SHAKE256: &str = "shake256";

pub const SUPPORTED_ALGORITHMS: [&str; 15] = [
pub const SUPPORTED_ALGORITHMS: [&str; 16] = [
ALGORITHM_OPTIONS_SYSV,
ALGORITHM_OPTIONS_BSD,
ALGORITHM_OPTIONS_CRC,
ALGORITHM_OPTIONS_CRC32B,
ALGORITHM_OPTIONS_MD5,
ALGORITHM_OPTIONS_SHA1,
ALGORITHM_OPTIONS_SHA3,
Expand Down Expand Up @@ -183,7 +185,7 @@ pub enum ChecksumError {
LengthOnlyForBlake2b,
#[error("the --binary and --text options are meaningless when verifying checksums")]
BinaryTextConflict,
#[error("--check is not supported with --algorithm={{bsd,sysv,crc}}")]
#[error("--check is not supported with --algorithm={{bsd,sysv,crc,crc32b}}")]
AlgorithmNotSupportedWithCheck,
#[error("You cannot combine multiple hash algorithms!")]
CombineMultipleAlgorithms,
Expand Down Expand Up @@ -334,6 +336,11 @@ pub fn detect_algo(algo: &str, length: Option<usize>) -> UResult<HashAlgorithm>
create_fn: Box::new(|| Box::new(CRC::new())),
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 {
name: ALGORITHM_OPTIONS_MD5,
create_fn: Box::new(|| Box::new(Md5::new())),
Expand Down
31 changes: 31 additions & 0 deletions src/uucore/src/lib/features/sum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
state: u16,
}
Expand Down
29 changes: 23 additions & 6 deletions tests/by-util/test_cksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,23 +301,31 @@ fn test_check_algo() {
.arg("lorem_ipsum.txt")
.fails()
.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=sysv")
.arg("--check")
.arg("lorem_ipsum.txt")
.fails()
.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=crc")
.arg("--check")
.arg("lorem_ipsum.txt")
.fails()
.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);
}

Expand Down Expand Up @@ -1661,10 +1669,11 @@ mod gnu_cksum_base64 {
use super::*;
use crate::common::util::log_info;

const PAIRS: [(&str, &str); 11] = [
const PAIRS: [(&str, &str); 12] = [
("sysv", "0 0 f"),
("bsd", "00000 0 f"),
("crc", "4294967295 0 f"),
("crc32b", "0 0 f"),
("md5", "1B2M2Y8AsgTpgAmY7PhCfg=="),
("sha1", "2jmj7l5rSw0yVb/vlWAYkK/YBwk="),
("sha224", "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw=="),
Expand Down Expand Up @@ -1693,7 +1702,7 @@ mod gnu_cksum_base64 {
}

fn output_format(algo: &str, digest: &str) -> String {
if ["sysv", "bsd", "crc"].contains(&algo) {
if ["sysv", "bsd", "crc", "crc32b"].contains(&algo) {
digest.to_string()
} else {
format!("{} (f) = {}", algo.to_uppercase(), digest).replace("BLAKE2B", "BLAKE2b")
Expand All @@ -1706,6 +1715,7 @@ mod gnu_cksum_base64 {
let scene = make_scene();

for (algo, digest) in PAIRS {
log_info(format!("ALGORITHM"), algo);
scene
.ucmd()
.arg("--base64")
Expand All @@ -1724,8 +1734,15 @@ mod gnu_cksum_base64 {
let scene = make_scene();

for (algo, digest) in PAIRS {
if ["sysv", "bsd", "crc"].contains(&algo) {
if ["sysv", "bsd", "crc", "crc32b"].contains(&algo) {
// 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;
}

Expand Down

0 comments on commit f89eb8b

Please sign in to comment.