Rustの標準ライブラリーだけで、ファイルのハッシュ値を計算したいことがある。ここでの目的は改竄防止ではなくて、「このディレクトリー内のファイルで、内容の重複した物(同じ画像が複数あるとか)を検出したい」といった場合に使う物。
プログラム内でだけ、ファイル内容の同一性を計算できればいいから、その結果を他のプログラムに渡したり、ユーザーの手元で再現できたり、みたいな必要はここではない。そういうのが必要な場合は、アルゴリズムが標準化されたSHA256とかDM5とかを使うのがよくて(コマンドラインで簡単に検証できるしね)、それ用のクレートを使おう。
use std::collections::hash_map::DefaultHasher;
use std::fs::File;
use std::hash::Hasher;
use std::io::{BufReader, Read};
use std::env::args;
fn main() {
let file_path = args().into_iter().nth(1).expect("Specify file to calculate hash");
println!("hash for {}: {}", &file_path, calculate_file_hash(&file_path));
}
fn calculate_file_hash(file_path: &str) -> u64 {
let file = File::open(file_path).expect("file path");
let mut reader = BufReader::new(file);
let mut hasher = DefaultHasher::new();
let mut buffer = [0; 1024];
while let Ok(n) = reader.read(&mut buffer) {
hasher.write(&buffer);
if n == 0 {
break;
}
}
hasher.finish()
}
cargo build
して実行すると結果が出力される。
% ./target/debug/rust-calculate-file-hash Cargo.toml
hash for Cargo.toml: 15721806948633906843
% ./target/debug/rust-calculate-file-hash Cargo.lock
hash for Cargo.lock: 15030569525137916044
% ./target/debug/rust-calculate-file-hash src/main.rs
hash for src/main.rs: 17726332095612413813
Comments
July 4, 2023 03:54
g4wh
This is an excellent piece of writing. This is without a doubt one of the most impressive entries I’ve ever seen. Your work is remarkable, and it inspires me to do better. I admire you. capybara clicker
February 27, 2023 04:33
std::io::Readトレイトを実装する構造体のインスタンスを作成します。Garten Of Banban 一般的に、std::io::BufReaderを使用すると、入力のバッファリングを行い、読み込みを最適化することができます。