feat: add --binary(-b) option to hash commands (#5885)

For instance,

```
echo 'abcdefghijklmnopqrstuvwxyz' | hash sha256 --binary
```

Will returns the hash as a binary value instead of a hexadecimaly encoded string.
This commit is contained in:
Benoît Cortier 2022-06-26 07:50:56 -04:00 committed by GitHub
parent a142d1a192
commit 32f0f94b46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 18 deletions

View file

@ -36,11 +36,17 @@ where
}
fn signature(&self) -> Signature {
Signature::build(self.name()).rest(
"rest",
SyntaxShape::CellPath,
format!("optionally {} hash data by cell path", D::name()),
)
Signature::build(self.name())
.switch(
"binary",
"Output binary instead of hexadecimal representation",
Some('b'),
)
.rest(
"rest",
SyntaxShape::CellPath,
format!("optionally {} hash data by cell path", D::name()),
)
}
fn usage(&self) -> &str {
@ -58,17 +64,20 @@ where
call: &Call,
input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let binary = call.has_flag("binary");
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
input.map(
move |v| {
if cell_paths.is_empty() {
action::<D>(&v)
action::<D>(binary, &v)
} else {
let mut v = v;
for path in &cell_paths {
let ret = v
.update_cell_path(&path.members, Box::new(move |old| action::<D>(old)));
let ret = v.update_cell_path(
&path.members,
Box::new(move |old| action::<D>(binary, old)),
);
if let Err(error) = ret {
return Value::Error { error };
}
@ -81,7 +90,7 @@ where
}
}
pub fn action<D>(input: &Value) -> Value
pub fn action<D>(binary: bool, input: &Value) -> Value
where
D: HashDigest,
digest::Output<D>: core::fmt::LowerHex,
@ -108,6 +117,17 @@ where
}
};
let val = format!("{:x}", D::digest(bytes));
Value::String { val, span }
let digest = D::digest(bytes);
if binary {
Value::Binary {
val: digest.to_vec(),
span,
}
} else {
Value::String {
val: format!("{:x}", digest),
span,
}
}
}

View file

@ -12,13 +12,24 @@ impl HashDigest for Md5 {
fn examples() -> Vec<Example> {
vec![
Example {
description: "md5 encode a string",
description: "get a hexadecimaly encoded string of the md5 digest of a string",
example: "echo 'abcdefghijklmnopqrstuvwxyz' | hash md5",
result: Some(Value::String {
val: "c3fcd3d76192e4007dfb496cca67e13b".to_owned(),
span: Span::test_data(),
}),
},
Example {
description: "get the md5 digest of a string in binary",
example: "echo 'abcdefghijklmnopqrstuvwxyz' | hash md5 --binary",
result: Some(Value::Binary {
val: vec![
0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c,
0xca, 0x67, 0xe1, 0x3b,
],
span: Span::test_data(),
}),
},
Example {
description: "md5 encode a file",
example: "open ./nu_0_24_1_windows.zip | hash md5",
@ -48,7 +59,7 @@ mod tests {
val: "c3fcd3d76192e4007dfb496cca67e13b".to_owned(),
span: Span::test_data(),
};
let actual = generic_digest::action::<Md5>(&binary);
let actual = generic_digest::action::<Md5>(false, &binary);
assert_eq!(actual, expected);
}
@ -62,7 +73,7 @@ mod tests {
val: "5f80e231382769b0102b1164cf722d83".to_owned(),
span: Span::test_data(),
};
let actual = generic_digest::action::<Md5>(&binary);
let actual = generic_digest::action::<Md5>(false, &binary);
assert_eq!(actual, expected);
}
}

View file

@ -12,7 +12,7 @@ impl HashDigest for Sha256 {
fn examples() -> Vec<Example> {
vec![
Example {
description: "sha256 encode a string",
description: "get a hexadecimaly encoded string of the sha256 digest of a string",
example: "echo 'abcdefghijklmnopqrstuvwxyz' | hash sha256",
result: Some(Value::String {
val: "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73"
@ -20,6 +20,18 @@ impl HashDigest for Sha256 {
span: Span::test_data(),
}),
},
Example {
description: "get the sha256 digest of a string in binary",
example: "echo 'abcdefghijklmnopqrstuvwxyz' | hash sha256 --binary",
result: Some(Value::Binary {
val: vec![
0x71, 0xc4, 0x80, 0xdf, 0x93, 0xd6, 0xae, 0x2f, 0x1e, 0xfa, 0xd1, 0x44,
0x7c, 0x66, 0xc9, 0x52, 0x5e, 0x31, 0x62, 0x18, 0xcf, 0x51, 0xfc, 0x8d,
0x9e, 0xd8, 0x32, 0xf2, 0xda, 0xf1, 0x8b, 0x73,
],
span: Span::test_data(),
}),
},
Example {
description: "sha256 encode a file",
example: "open ./nu_0_24_1_windows.zip | hash sha256",
@ -49,7 +61,7 @@ mod tests {
val: "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73".to_owned(),
span: Span::test_data(),
};
let actual = generic_digest::action::<Sha256>(&binary);
let actual = generic_digest::action::<Sha256>(false, &binary);
assert_eq!(actual, expected);
}
@ -63,7 +75,7 @@ mod tests {
val: "c47a10dc272b1221f0380a2ae0f7d7fa830b3e378f2f5309bbf13f61ad211913".to_owned(),
span: Span::test_data(),
};
let actual = generic_digest::action::<Sha256>(&binary);
let actual = generic_digest::action::<Sha256>(false, &binary);
assert_eq!(actual, expected);
}
}

View file

@ -23,7 +23,7 @@ impl Command for DecodeBase64 {
)
.switch(
"binary",
"do not decode payload as UTF-8 and output binary",
"Output a binary value instead of decoding payload as UTF-8",
Some('b'),
)
.rest(