public void VerifyFileHash() { var sw = Stopwatch.StartNew(); Log.Trace("Verifying file hash of PTable '{0}' started...", Path.GetFileName(Filename)); #if __MonoCS__ var workItem = GetWorkItem(); var stream = workItem.Stream; try { #else using (var stream = UnbufferedFileReadStream.Open(_filename)) { #endif //stream.Position = 0; var hash = MD5Hash.GetHashFor(stream, 0, stream.Length - MD5Size); var fileHash = new byte[MD5Size]; stream.Read(fileHash, 0, MD5Size); if (hash == null) { throw new CorruptIndexException(new HashValidationException("Calculated MD5 hash is null!")); } if (fileHash.Length != hash.Length) { throw new CorruptIndexException( new HashValidationException( string.Format( "Hash sizes differ! FileHash({0}): {1}, hash({2}): {3}.", fileHash.Length, BitConverter.ToString(fileHash), hash.Length, BitConverter.ToString(hash)))); } for (int i = 0; i < fileHash.Length; i++) { if (fileHash[i] != hash[i]) { throw new CorruptIndexException( new HashValidationException( string.Format( "Hashes are different! FileHash: {0}, hash: {1}.", BitConverter.ToString(fileHash), BitConverter.ToString(hash)))); } } } #if __MonoCS__ finally { ReturnWorkItem(workItem); } #endif Log.Trace("Verifying file hash of PTable '{0}' ({1} entries) done in {2}.", Path.GetFileName(Filename), Count, sw.Elapsed); }
public void VerifyFileHash() { if (!IsReadOnly) { throw new InvalidOperationException("You can't verify hash of not-completed TFChunk."); } Log.Trace("Verifying hash for TFChunk '{0}'...", _filename); #if __MonoCS__ using (var reader = AcquireReader()) { reader.Stream.Seek(0, SeekOrigin.Begin); var stream = reader.Stream; #else using (var reader = UnbufferedFileReadStream.Open(_filename)) { var stream = reader; #endif var footer = _chunkFooter; byte[] hash; using (var md5 = MD5.Create()) { // hash header and data MD5Hash.ContinuousHashFor(md5, stream, 0, ChunkHeader.Size + footer.PhysicalDataSize); // hash mapping and footer except MD5 hash sum which should always be last MD5Hash.ContinuousHashFor(md5, stream, ChunkHeader.Size + footer.PhysicalDataSize, footer.MapSize + ChunkFooter.Size - ChunkFooter.ChecksumSize); md5.TransformFinalBlock(Empty.ByteArray, 0, 0); hash = md5.Hash; } if (footer.MD5Hash == null || footer.MD5Hash.Length != hash.Length) { throw new HashValidationException(); } for (int i = 0; i < hash.Length; ++i) { if (footer.MD5Hash[i] != hash[i]) { throw new HashValidationException(); } } } }