Krusen/BencodeNET

NumberOfPieces != Pieces.Length

Closed this issue · 6 comments

I do have some torrents where the calculated NumberOfPieces property differs from the actual number of pieces Pieces.Length / 20.

An example:

  • TotalSize = 4034584869
  • PieceSize = 524288
  • NumberOfPieces = 7696 (int)Math.Ceiling((double)TotalSize / PieceSize)

The length of the Pieces array is 154120, hence the actual number of pieces - at least the ones we have checksums for - is 154120 / 20 = 7706.

This is not really a bug because the torrent itself seems to be inconsistent. However it might be a good idea to check this if the torrent is parsed with TorrentParserMode.Strict.

Yea, this is the torrent-related stuff I'm not so interested in maintaining :)

However, TotalSize is just a custom property I've added to easily sum all the file sizes. And NumberOfPieces should probably rather use Pieces.Length for the calculation instead of TotalSize. So I'll change that.

Since the Pieces array consists of 20 bytes long SHA1 hashes of the torrent's peaces, the solution should probably be Pieces.Length / 20. As far as I can say PieceLength doesn't really play a role here...

You're right, I was a bit quick there. But now I actually think that it's actually just NumberOfPieces == Pieces.Length, which makes the property useless.

The byte[] Pieces property is:

A concatenation of all 20-byte SHA1 hash values (one for each piece).

With "one for each piece" I don't see how they would differ. Thoughts?

I think originally it was meant to be for counting how many pieces the files themselves would take up. I'm not sure why that would ever be useful though.

But now I actually think that it's actually just NumberOfPieces == Pieces.Length, which makes the property useless.

The thing is that Pieces is actually an array of the pieces' hashes, each being 20 bytes long. That makes Pieces twenty times the size. You even mention it in one of your todos:

// TODO: Split into list of 20-byte hashes and rename to something appropriate?

What about creating a new Piece class, containing the 20-byte hash as a Hash property? That way you'd a) get rid of the need for a NumberOfPieces property because Pieces.Length would be exactly that and b) have those hashes handy for a check.

You're right. It all makes sense now :D

I'm fixing NumberOfPieces.