🌊
System.IO.HashingのxxHashを使っててハマった話
概要
ファイルコピーにおけるチェックサムとしてMD5を使っていたのですが、xxHashを使ったらどれくらい速くなるのか試してみたくなり使ってみた所、進捗をレポートする処理でハッシュが不正になってしまう現象に遭遇しました。色々調査した結果改善できたので共有します。
結論
AsSpan
を使って読み込んだデータだけ送るようにすれば直りました。
private byte[] GetXxHash3(string filename)
{
var hashAlgorithm = new XxHash3();
var bufferSize = 1024 * 1024; // 1MB
var buffer = new byte[bufferSize];
using (var entryStream = System.IO.File.OpenRead(filename))
{
var bytesRead = entryStream.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
// AsSpanを使って読み込んだデータだけAppendする。
hashAlgorithm.Append(buffer.AsSpan(0, bytesRead));
// 元々は以下のように書いてた。
// hashAlgorithm.Append(buffer);
// 処理を以下に書く。
}
}
return hashAlgorithm.GetHashAndReset());
}
経緯
元々MD5でチェックサムを実装していたのはTransformBlock
とTransformFinalBlock
を使って進捗レポートを送りながらハッシュを計算していました。ですがチェックサムでMD5を使うのは重いので、高速なxxHashに切り替えたらどれくらい速くなるのかが気になってやってみようと思いました。
xxHashのOSSをいろいろ探っていたのですが、.NET Platform Extensions
で公式から配布されている事が分かり、導入してみました。NuGetで配布されています。
netstandard2.0で実装されているのが素晴らしい!!!
これを導入して色々使い方を調べたら、どうやらAppend
メソッドを使えば進捗レポートを送りつつハッシュ計算ができるのでは?と思って作っていました。
ただこれだと全然違うハッシュが生成されてしまうので更に調べまくった結果、バッファをそのままAppend
メソッドに送ってはいけないという事にたどり着きました。
Discussion