如何在 Rust 中散列二进制文件
How to hash a binary file in 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
}
输出是:
...
Error { kind: InvalidData, message: "stream did not contain valid UTF-8" }
编辑:
升级到 sha256 = "1.0.3"
应该可以解决这个问题
问题是 digest_file
正在内部将文件读取到 String
,这要求它包含有效的 UTF-8,在这种情况下这显然不是您想要的。
相反,您可以以字节形式读取文件并将其传递到 sha256::digest_bytes
:
let bytes = std::fs::read(path).unwrap(); // Vec<u8>
let hash = sha256::digest_bytes(&bytes);
所依赖的 sha2
crate 支持散列 Read
able 对象,而无需将整个文件读入内存。请参阅 hashes readme.
中的示例
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();
这是一个使用 sha2
crate 的实现,它不会将整个文件读入内存,也不依赖于 ring crate。就我而言,戒指不是纯锈,这会导致 cross-compilation 困难。
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()))
}
在 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
}
输出是:
...
Error { kind: InvalidData, message: "stream did not contain valid UTF-8" }
编辑:
升级到 sha256 = "1.0.3"
应该可以解决这个问题
问题是 digest_file
正在内部将文件读取到 String
,这要求它包含有效的 UTF-8,在这种情况下这显然不是您想要的。
相反,您可以以字节形式读取文件并将其传递到 sha256::digest_bytes
:
let bytes = std::fs::read(path).unwrap(); // Vec<u8>
let hash = sha256::digest_bytes(&bytes);
所依赖的 sha2
crate 支持散列 Read
able 对象,而无需将整个文件读入内存。请参阅 hashes readme.
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();
这是一个使用 sha2
crate 的实现,它不会将整个文件读入内存,也不依赖于 ring crate。就我而言,戒指不是纯锈,这会导致 cross-compilation 困难。
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()))
}