0

環境: 末尾に 28 バイトの SHA-1 チェックサムが追加された 3 GB のデータ ファイル。

FileStream または他のタイプのストリームを使用して、追加されたチェックサムを物理的に削除せずに、ストリームを位置 0 から位置 [x - 28(追加されたチェックサムの長さ)] まで読み取ることにより、SHA-1 チェックサム ハッシュを計算することは可能ですか?最初にファイルの終わり?

現在、FileStream を使用してファイルを開き、BinaryReader を使用して読み取り、ファイルの最後の 28 バイトをシークして読み取ります。

次に、FileStream を使用してファイルを再度開き、ストリームの長さを 28 バイトに設定すると、ファイルからチェックサムが削除されます。

最後に、最後の 28 バイトを削除してデータ ファイルのチェックサムを計算し、それをファイルの末尾から削除したチェックサムと比較して、チェックサムが一致していることを確認します。

基本的に、追加されたチェックサムを最初に削除しなくても、ファイルのデータ部分のチェックサムを計算できるかどうかを知りたいです。

4

2 に答える 2

5

本当に読みたいデータの量(つまり、長さ - 28 バイト) がわかっている場合は、ハッシュを計算するときに、その量のデータだけを入れます。ハッシュを計算する方法を正確に述べていませんが、通常、ハッシュ計算にさらにデータを繰り返し「書き込む」ことができます.最後の28バイトに達するまで、必要なだけそれを行ってください.

サンプル:

public byte[] Sha1ExceptEnd(Stream input, int bytesToOmit)
{
    long bytesToRead = input.Length - bytesToOmit;
    byte[] buffer = new byte[16 * 1024]; // Hash up to 16K at a time
    using (SHA1 sha1 = SHA1.Create())
    {
        while (bytesToRead > 0)
        {
            int thisPass = (int) Math.Min(buffer.Length, bytesToRead);
            int bytesReadThisPass = input.Read(buffer, 0, thisPass);
            if (bytesReadThisPass <= 0)
            {
                throw new IOException("Unexpected end of data");
            }  
            sha1.TransformBlock(buffer, 0, bytesReadThisPass, buffer, 0);
            bytesToRead -= bytesReadThisPass;
        }
        // Flush the hash
        sha1.TransformFinalBlock(buffer, 0, 0);
        return sha1.Hash;
    }
}
于 2012-07-06T21:38:52.843 に答える
0

ファンシーな方法は、指定された基になるストリームのサブセクションを読み取るラッパー Stream オブジェクトを作成することです。このようにして、FileStream のすべてのサブ部分に対して他のオブジェクト (リーダーなど) を構築できます。

関心のある範囲でストリームからバイトを直接読み取る方がはるかに簡単です。

于 2012-07-06T21:40:25.723 に答える