散列 torrent 文件片段
Hashing torrent file pieces
我正在尝试计算和比较 torrent 文件片段的哈希值,并且 运行 遇到一个问题,根据我的文件,我得到的哈希值比 torrent 应用程序生成的 torrent 文件更多。
我有一个哈希函数来计算文件片段的哈希值,每个文件都经过它
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;
}
正如我所说,问题是在所有文件的散列结束时,我的文件比 torrent 文件多一点。
我应该以不同的方式处理哈希吗?
我知道在文件末尾,文件中剩余的数据小于片段大小是很常见的,但不确定应该如何处理这种情况。
您对这一行的假设不正确:
(CALL_READ = await inputStream.ReadAsync(BUFFER, 0, blockSize, ct)
Stream.Read
不保证 blockSize
- 实际会读取许多字节,您应该在 ReadAsync
调用完成后检查是否 CALL_READ == blockSize
以及是否不是那么你应该专门处理这种情况。
这将是一个正确的方法:
+-----------------+-----------------+-----------------+-----------------+
| Piece 0 | Piece 1 | Piece 2 | Piece 3 |
+-----------------+-----------------+-----------------+-----------------+
| File A | File B | <- file B does not end at the end of piece 3
+-----------------+-----------------+-----------------+-----------------+
这是一种不正确的方法:
+-----------------+-----------------+-----------------+-----------------+
| Piece 0 | Piece 1 | Piece 2 | Piece 3 |
+-----------------+-----------------+-----------------+-----------------+
| File A |00000000| File B |000|
+-----------------+-----------------+-----------------+-----------------+
我正在尝试计算和比较 torrent 文件片段的哈希值,并且 运行 遇到一个问题,根据我的文件,我得到的哈希值比 torrent 应用程序生成的 torrent 文件更多。
我有一个哈希函数来计算文件片段的哈希值,每个文件都经过它
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;
}
正如我所说,问题是在所有文件的散列结束时,我的文件比 torrent 文件多一点。 我应该以不同的方式处理哈希吗? 我知道在文件末尾,文件中剩余的数据小于片段大小是很常见的,但不确定应该如何处理这种情况。
您对这一行的假设不正确:
(CALL_READ = await inputStream.ReadAsync(BUFFER, 0, blockSize, ct)
Stream.Read
不保证 blockSize
- 实际会读取许多字节,您应该在 ReadAsync
调用完成后检查是否 CALL_READ == blockSize
以及是否不是那么你应该专门处理这种情况。
这将是一个正确的方法:
+-----------------+-----------------+-----------------+-----------------+
| Piece 0 | Piece 1 | Piece 2 | Piece 3 |
+-----------------+-----------------+-----------------+-----------------+
| File A | File B | <- file B does not end at the end of piece 3
+-----------------+-----------------+-----------------+-----------------+
这是一种不正确的方法:
+-----------------+-----------------+-----------------+-----------------+
| Piece 0 | Piece 1 | Piece 2 | Piece 3 |
+-----------------+-----------------+-----------------+-----------------+
| File A |00000000| File B |000|
+-----------------+-----------------+-----------------+-----------------+