I'm computing the SHA1 digest in Rust via sha1
crate and use the values as a part of a larger utility.
use sha1::{Digest, Sha1};
fn main() {
for s in vec![
"a",
"string",
"some text",
"https://example.com",
] {
compute_digest(s);
}
}
fn compute_digest(s: &str) {
let mut hasher = Sha1::new();
hasher.update(s);
let digest = hasher.finalize();
println!("{s:20} -> {digest:x}");
}
The output:
a -> 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
string -> ecb252044b5ea0f679ee78ec1a12904739e2904d
some text -> 37aa63c77398d954473262e1a0057c1e632eda77
https://example.com -> 327c3fda87ce286848a574982ddd0b7c7487f816
I created a test where I compare the actually computed keys with expected values. The expected values computed using shasum
utility (macOS) as follows. But the output is different from the crate's results.
echo "a" | shasum -a 1
# 3f786850e387550fdab836ed7e6dc881de23001b
echo "string" | shasum -a 1
# edbf08a562d55ca08be8d118430892695f28d432
echo "some text" | shasum -a 1
# a5c341bec5c89ed16758435069e3124b3685ad93
echo "https://example.com" | shasum -a 1
# 104f444c99548d6fcc870aeddf94096b790ff56e
Why is that? I guess there is some difference in the functionality of the default Sha1::new()
instance and shasum
, but I cannot grasp what it is.
The reason is that echo
always appends a newline to the output. Thus, the output you're getting for echo "a"
contains the two bytes 0x61 and 0x0a, whereas your hash of a
in Rust is only computing the byte 0x61.
If you want to verify these at the command line, use printf
instead. Note that the first argument contains a format string (just like for printf(3)
), so if you want to include a percent sign, you either need to double it or write printf '%s' "$ARGUMENT"
.
So doing that makes this work properly:
$ printf 'a' | shasum -a 1
86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -
$ printf 'a\n' | shasum -a 1
3f786850e387550fdab836ed7e6dc881de23001b -
Note, however, that SHA-1 is insecure and should not be used in any new software. If you need a cryptographic hash function, use SHA-256 (or any of the SHA-2, SHA-3, or BLAKE2 hashes) instead.