NullReference
NullReference

Reputation: 1036

Hashing torrent file pieces

I am trying to calculate and compare torrent file pieces hashes and have run into a problem where based on my files i get more hashes then in torrent file generated by torrent applications.

I have a hashing function to calculate hashes of the file pieces and each file goes through it

      public static async Task<IEnumerable<byte[]>> CreateHashTableAsync(HashAlgorithm provider,
        Stream inputStream,
        int blockSize,
        IBufferManager bufferManager,
        CancellationToken ct)
    {
        if (provider == null)
            throw new ArgumentNullException(nameof(provider));

        if (inputStream == null)
            throw new ArgumentNullException(nameof(inputStream));

        if (bufferManager == null)
            throw new ArgumentNullException(nameof(bufferManager));

        var HASH_TABLE = new List<byte[]>();

        var BUFFER = bufferManager.TakeBuffer(blockSize);

        int CALL_READ = 0;
        while ((CALL_READ = await inputStream.ReadAsync(BUFFER, 0, blockSize, ct).ConfigureAwait(false)) > 0)
        {                
            ct.ThrowIfCancellationRequested();
            var BLOCK_HASH = provider.ComputeHash(BUFFER, 0, CALL_READ);
            HASH_TABLE.Add(BLOCK_HASH);
        }

        BUFFER = null;

        return HASH_TABLE;

    }

As i said the problem is that at the end of hashing of all files i have a little more pieces than in torrent file. Should i handle the hashing differently ? I understand that at the end of the file its common that the data remaining in file is less than the piece size but not sure how this situation should be handled.

Upvotes: 0

Views: 1265

Answers (2)

aljazsim
aljazsim

Reputation: 404

This would be a correct approach:

+-----------------+-----------------+-----------------+-----------------+
| Piece 0         | Piece 1         | Piece 2         | Piece 3         |
+-----------------+-----------------+-----------------+-----------------+
| File A                   | File B                        | <- file B does not end at the end of piece 3
+-----------------+-----------------+-----------------+-----------------+

This would be an incorrect approach:

+-----------------+-----------------+-----------------+-----------------+
| Piece 0         | Piece 1         | Piece 2         | Piece 3         |
+-----------------+-----------------+-----------------+-----------------+
| File A                   |00000000| File B                        |000| 
+-----------------+-----------------+-----------------+-----------------+

Upvotes: 1

Dai
Dai

Reputation: 155608

You have an incorrect assumption on this line:

(CALL_READ = await inputStream.ReadAsync(BUFFER, 0, blockSize, ct)

Stream.Read does not guarantee that blockSize-many bytes will actually be read, you should check to see if CALL_READ == blockSize after the call to ReadAsync completes and if it doesn't then you should handle that case specifically.

Upvotes: 1

Related Questions