- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
public class ASyncFileHashAlgorithm
	{
		protected HashAlgorithm hashAlgorithm;
		protected byte[] hash;
		protected bool cancel = false;
		protected int bufferSize = 4096;
		public delegate void FileHashingProgressHandler (object sender, FileHashingProgressArgs e);
		public event FileHashingProgressHandler FileHashingProgress;
		public ASyncFileHashAlgorithm(HashAlgorithm hashAlgorithm)
		{
			this.hashAlgorithm = hashAlgorithm;
		}
		public byte[] ComputeHash(Stream stream)
		{
			cancel = false;
			hash = null;
			int _bufferSize = bufferSize; // this makes it impossible to change the buffer size while computing
			byte[] readAheadBuffer, buffer;
			int readAheadBytesRead, bytesRead;
			long size, totalBytesRead = 0;
			size = stream.Length;
         	readAheadBuffer = new byte[_bufferSize];
            readAheadBytesRead = stream.Read(readAheadBuffer, 0, readAheadBuffer.Length);
            totalBytesRead += readAheadBytesRead;    
            do
            {
                bytesRead = readAheadBytesRead;
                buffer = readAheadBuffer;    
                readAheadBuffer = new byte[_bufferSize];
                readAheadBytesRead = stream.Read(readAheadBuffer, 0, readAheadBuffer.Length);
                totalBytesRead += readAheadBytesRead;    
                if (readAheadBytesRead == 0)
                    hashAlgorithm.TransformFinalBlock(buffer, 0, bytesRead);
                else
                    hashAlgorithm.TransformBlock(buffer, 0, bytesRead, buffer, 0);
				FileHashingProgress(this, new FileHashingProgressArgs(totalBytesRead, size));
            } while (readAheadBytesRead != 0 && !cancel);
			if(cancel)
				return hash = null;
    		return hash = hashAlgorithm.Hash;
		}
		public int BufferSize
		{
			get
			{ return bufferSize; }
			set
			{ bufferSize = value; }
		}
		public byte[] Hash
		{
			get
			{ return hash; }
		}
		public void Cancel()
		{
			cancel = true;
		}
		public override string ToString ()
		{
			string hex = "";
			foreach(byte b in Hash)
				hex += b.ToString("x2");
			return hex;
		}
	}