mirror of
https://github.com/uutils/coreutils
synced 2024-11-15 09:27:21 +00:00
cksum: implement and test --base64 output method
This commit is contained in:
parent
7b219aee63
commit
133cdde885
15 changed files with 100 additions and 15 deletions
|
@ -15,6 +15,7 @@ use std::io::{self, stdin, stdout, BufReader, Read, Write};
|
|||
use std::iter;
|
||||
use std::path::Path;
|
||||
use uucore::{
|
||||
encoding,
|
||||
error::{FromIo, UError, UResult, USimpleError},
|
||||
format_usage, help_about, help_section, help_usage, show,
|
||||
sum::{
|
||||
|
@ -44,6 +45,13 @@ enum CkSumError {
|
|||
RawMultipleFiles,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum OutputFormat {
|
||||
Hexadecimal,
|
||||
Raw,
|
||||
Base64,
|
||||
}
|
||||
|
||||
impl UError for CkSumError {
|
||||
fn code(&self) -> i32 {
|
||||
match self {
|
||||
|
@ -138,7 +146,7 @@ struct Options {
|
|||
output_bits: usize,
|
||||
untagged: bool,
|
||||
length: Option<usize>,
|
||||
raw: bool,
|
||||
output_format: OutputFormat,
|
||||
}
|
||||
|
||||
/// Calculate checksum
|
||||
|
@ -153,7 +161,7 @@ where
|
|||
I: Iterator<Item = &'a OsStr>,
|
||||
{
|
||||
let files: Vec<_> = files.collect();
|
||||
if options.raw && files.len() > 1 {
|
||||
if options.output_format == OutputFormat::Raw && files.len() > 1 {
|
||||
return Err(Box::new(CkSumError::RawMultipleFiles));
|
||||
}
|
||||
|
||||
|
@ -177,7 +185,7 @@ where
|
|||
};
|
||||
Box::new(file_buf) as Box<dyn Read>
|
||||
});
|
||||
let (sum, sz) = digest_read(&mut options.digest, &mut file, options.output_bits)
|
||||
let (sum_hex, sz) = digest_read(&mut options.digest, &mut file, options.output_bits)
|
||||
.map_err_context(|| "failed to read input".to_string())?;
|
||||
if filename.is_dir() {
|
||||
show!(USimpleError::new(
|
||||
|
@ -186,17 +194,25 @@ where
|
|||
));
|
||||
continue;
|
||||
}
|
||||
if options.raw {
|
||||
let bytes = match options.algo_name {
|
||||
ALGORITHM_OPTIONS_CRC => sum.parse::<u32>().unwrap().to_be_bytes().to_vec(),
|
||||
ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => {
|
||||
sum.parse::<u16>().unwrap().to_be_bytes().to_vec()
|
||||
}
|
||||
_ => decode(sum).unwrap(),
|
||||
};
|
||||
stdout().write_all(&bytes)?;
|
||||
return Ok(());
|
||||
}
|
||||
let sum = match options.output_format {
|
||||
OutputFormat::Raw => {
|
||||
let bytes = match options.algo_name {
|
||||
ALGORITHM_OPTIONS_CRC => sum_hex.parse::<u32>().unwrap().to_be_bytes().to_vec(),
|
||||
ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => {
|
||||
sum_hex.parse::<u16>().unwrap().to_be_bytes().to_vec()
|
||||
}
|
||||
_ => decode(sum_hex).unwrap(),
|
||||
};
|
||||
// Cannot handle multiple files anyway, output immediately.
|
||||
stdout().write_all(&bytes)?;
|
||||
return Ok(());
|
||||
}
|
||||
OutputFormat::Hexadecimal => sum_hex,
|
||||
OutputFormat::Base64 => match options.algo_name {
|
||||
ALGORITHM_OPTIONS_CRC | ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => sum_hex,
|
||||
_ => encoding::encode(encoding::Format::Base64, &decode(sum_hex).unwrap()).unwrap(),
|
||||
},
|
||||
};
|
||||
// The BSD checksum output is 5 digit integer
|
||||
let bsd_width = 5;
|
||||
match (options.algo_name, not_file) {
|
||||
|
@ -289,6 +305,7 @@ mod options {
|
|||
pub const TAG: &str = "tag";
|
||||
pub const LENGTH: &str = "length";
|
||||
pub const RAW: &str = "raw";
|
||||
pub const BASE64: &str = "base64";
|
||||
}
|
||||
|
||||
#[uucore::main]
|
||||
|
@ -343,13 +360,21 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
let (name, algo, bits) = detect_algo(algo_name, length);
|
||||
|
||||
let output_format = if matches.get_flag(options::RAW) {
|
||||
OutputFormat::Raw
|
||||
} else if matches.get_flag(options::BASE64) {
|
||||
OutputFormat::Base64
|
||||
} else {
|
||||
OutputFormat::Hexadecimal
|
||||
};
|
||||
|
||||
let opts = Options {
|
||||
algo_name: name,
|
||||
digest: algo,
|
||||
output_bits: bits,
|
||||
length,
|
||||
untagged: matches.get_flag(options::UNTAGGED),
|
||||
raw: matches.get_flag(options::RAW),
|
||||
output_format,
|
||||
};
|
||||
|
||||
match matches.get_many::<String>(options::FILE) {
|
||||
|
@ -420,5 +445,14 @@ pub fn uu_app() -> Command {
|
|||
.help("emit a raw binary digest, not hexadecimal")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::BASE64)
|
||||
.long(options::BASE64)
|
||||
.help("emit a base64 digest, not hexadecimal")
|
||||
.action(ArgAction::SetTrue)
|
||||
// Even though this could easily just override an earlier '--raw',
|
||||
// GNU cksum does not permit these flags to be combined:
|
||||
.conflicts_with(options::RAW),
|
||||
)
|
||||
.after_help(AFTER_HELP)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ pub enum DecodeError {
|
|||
Io(#[from] io::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EncodeError {
|
||||
Z85InputLenNotMultipleOf4,
|
||||
InvalidInput,
|
||||
|
|
|
@ -363,6 +363,43 @@ fn test_raw_multiple_files() {
|
|||
.code_is(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_base64_raw_conflicts() {
|
||||
new_ucmd!()
|
||||
.arg("--base64")
|
||||
.arg("--raw")
|
||||
.arg("lorem_ipsum.txt")
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.stderr_contains("--base64")
|
||||
.stderr_contains("cannot be used with")
|
||||
.stderr_contains("--raw");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_base64_single_file() {
|
||||
for algo in ALGOS {
|
||||
new_ucmd!()
|
||||
.arg("--base64")
|
||||
.arg("lorem_ipsum.txt")
|
||||
.arg(format!("--algorithm={algo}"))
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_is_fixture_bytes(format!("base64/{algo}_single_file.expected"));
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_base64_multiple_files() {
|
||||
new_ucmd!()
|
||||
.arg("--base64")
|
||||
.arg("--algorithm=md5")
|
||||
.arg("lorem_ipsum.txt")
|
||||
.arg("alice_in_wonderland.txt")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_is_fixture_bytes(format!("base64/md5_multiple_files.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fail_on_folder() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
|
1
tests/fixtures/cksum/base64/blake2b_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/blake2b_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
BLAKE2b (lorem_ipsum.txt) = DpegkYnlYMN4nAv/HwIBZoYe+FfR+/5FdN4YQuPAbKu5V15K9jCaFmFYwrQI08A4wbSdgos1FYFCzcA5bRGVww==
|
1
tests/fixtures/cksum/base64/bsd_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/bsd_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
08109 1 lorem_ipsum.txt
|
1
tests/fixtures/cksum/base64/crc_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/crc_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
378294376 772 lorem_ipsum.txt
|
2
tests/fixtures/cksum/base64/md5_multiple_files.expected
vendored
Normal file
2
tests/fixtures/cksum/base64/md5_multiple_files.expected
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
MD5 (lorem_ipsum.txt) = zXJGkPfcYXdd+sQApx8sqg==
|
||||
MD5 (alice_in_wonderland.txt) = 9vpwM+FhZqlYmqHAOI/9WA==
|
1
tests/fixtures/cksum/base64/md5_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/md5_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
MD5 (lorem_ipsum.txt) = zXJGkPfcYXdd+sQApx8sqg==
|
1
tests/fixtures/cksum/base64/sha1_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/sha1_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
SHA1 (lorem_ipsum.txt) = qx3QuuHYiDo9GKZt5q+9KCUs++8=
|
1
tests/fixtures/cksum/base64/sha224_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/sha224_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
SHA224 (lorem_ipsum.txt) = PeZvvK0QbhtAqzkb5WxR0gB+sfnGVdD04pv8AQ==
|
1
tests/fixtures/cksum/base64/sha256_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/sha256_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
SHA256 (lorem_ipsum.txt) = 98QgUBxQ4AswklAQDWfqXpEJgVNrRYL+nENb2Ss/HwI=
|
1
tests/fixtures/cksum/base64/sha384_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/sha384_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
SHA384 (lorem_ipsum.txt) = S+S5Cg0NMpZpkpIQGfJKvIJNz7ixxAgQLx9niPuAupqaTFp7V1ozU6kKjucZSB3L
|
1
tests/fixtures/cksum/base64/sha512_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/sha512_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
SHA512 (lorem_ipsum.txt) = llRkqyVWqtWOvHPYmtIh5Vl5dSnsr8D0ZsEXlc/21uLGD5agfFQs/R9Cbl5P4KSKoVZnukQJayE9CBPNA436BQ==
|
1
tests/fixtures/cksum/base64/sm3_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/sm3_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
SM3 (lorem_ipsum.txt) = bSlrgF0GC/7SKAjfMI27m0MXeU3U7WdAoQdwp4Jpm8I=
|
1
tests/fixtures/cksum/base64/sysv_single_file.expected
vendored
Normal file
1
tests/fixtures/cksum/base64/sysv_single_file.expected
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
6985 2 lorem_ipsum.txt
|
Loading…
Reference in a new issue