计算部分流的 MD5 哈希



我有一个以自定义文件格式存储的大型数据集(~1GB),其中的最后16个字节是文件所有先前字节的MD5哈希。

我想使用 HashAlgorithm.ComputeHash(Stream) 根据嵌入式 MD5 验证此文件的 MD5,但是这将计算整个文件的哈希,包括最后 16 字节的哈希,这显然不起作用。

如何计算流的一部分的 MD5 哈希?我知道我可以将流读入数组并将其传递给HashAlgorithm.ComputeHash(Bytes),但是在内存中复制这1GB数据的开销令人望而却步。

从这里获取,您还可以获得其他方法。

创建一个部分文件流类,读取所需的大小并对其进行哈希处理。

 class PartialFileStream : FileStream
{
    public PartialFileStream(string path, FileMode mode, long startPosition, long endPosition): base(path, mode)
{
  base.Seek(startPosition, SeekOrigin.Begin);
  ReadTillPosition = endPosition;
}
public long ReadTillPosition { get; set; }
public override int Read(byte[] array, int offset, int count)
{
 if (base.Position >= this.ReadTillPosition)
   return 0;
 if (base.Position + count > this.ReadTillPosition)
   count = (int)(this.ReadTillPosition - base.Position);
 return base.Read(array, offset, count);
  }
}

您可以使用 FileStream.Seek 选项查找流的特定位置并从那里读取。

我发现自己在 6 个月内第二次需要这个,所以为部分输入流发布我的解决方案。

class PartialStream: Stream {
    public Stream Source { get; }
    public long Offset { get; }
    public override long Length { get; }
    private long End => Offset + Length;
    public override bool CanRead => true;
    public override bool CanSeek => false;
    public override bool CanWrite => false;
    public override long Position {
        get => Source.Position - Offset;
        set => throw new NotSupportedException();
    }
    public PartialStream(Stream source, long length) {
        Offset = source.Position;
        Length = length;
    }
    public PartialStream(Stream source, long offset, long length, bool seekToOffset = true) {
        if (seekToOffset) source.Seek(offset, SeekOrigin.Begin);
        Offset = offset;
        Length = length;
    }
    public override int Read(byte[] array, int offset, int count) {
        if (Source.Position >= End) return 0;
        if (Source.Position + count > End)
            count = (int)(End - Source.Position);
        return Source.Read(array, offset, count);
    }
    public override void Flush() => throw new NotSupportedException();
    public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
    public override void SetLength(long value) => throw new NotSupportedException();
    public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
}

相关内容

  • 没有找到相关文章

最新更新