Search code examples
rusthashsha1

Rust sha1::Sha1 result is different from shasum


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.


Solution

  • 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.