如何在 Rust 中对二进制文件进行哈希处理

Mih*_*los 9 sha256 rust

在 Rust 中,使用sha256 = "1.0.2"(或类似),如何散列二进制文件(即tar.gz存档)?

我正在尝试获取该二进制文件的 sha256。

这不起作用:

fn hash() {
    let file = "file.tar.gz";
    let computed_hash = sha256::digest_file(std::path::Path::new(file)).unwrap();
    computed_hash
}
Run Code Online (Sandbox Code Playgroud)

输出是:

...
Error { kind: InvalidData, message: "stream did not contain valid UTF-8" }
Run Code Online (Sandbox Code Playgroud)

cam*_*024 16

编辑:升级到sha256 = "1.0.3"应该可以解决这个问题

问题是digest_file在内部将文件读取到 a String,这要求它包含有效的 UTF-8,这显然不是您在这种情况下想要的。

相反,您可以以字节形式读取文件并将其传递到sha256::digest_bytes

let bytes = std::fs::read(path).unwrap();  // Vec<u8>
let hash = sha256::digest_bytes(&bytes);
Run Code Online (Sandbox Code Playgroud)


Lee*_*Lee 12

sha2所依赖的 crate 支持对可散列的对象进行哈希处理,Read而无需将整个文件读入内存。请参阅哈希自述文件中的示例。

use sha2::{Sha256, Digest};
use std::{io, fs};

let mut hasher = Sha256::new();
let mut file = fs::File::open("file.tar.gz")?;

let bytes_written = io::copy(&mut file, &mut hasher)?;
let hash_bytes = hasher.finalize();
Run Code Online (Sandbox Code Playgroud)


小智 6

这是使用 crate 的实现sha2,它不会将整个文件读入内存,并且不依赖于 Ring crate。就我而言,ring 并不是纯粹的 Rust,这会导致交叉编译困难。

use data_encoding::HEXLOWER;
use sha2::{Digest, Sha256};
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::{Path, PathBuf};

/// calculates sha256 digest as lowercase hex string
fn sha256_digest(path: &PathBuf) -> Result<String> {
    let input = File::open(path)?;
    let mut reader = BufReader::new(input);

    let digest = {
        let mut hasher = Sha256::new();
        let mut buffer = [0; 1024];
        loop {
            let count = reader.read(&mut buffer)?;
            if count == 0 { break }
            hasher.update(&buffer[..count]);
        }
        hasher.finalize()
    };
    Ok(HEXLOWER.encode(digest.as_ref()))
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您不需要`HEXLOWER`,您可以使用`format!("{:X}",digest)` (2认同)