using System; using System.Linq; using System.Security.Cryptography; using System.Threading.Tasks; using SabreTools.Library.Data; namespace SabreTools.Library.Tools { /// /// Async hashing class wraper /// public class Hasher { public Hash HashType { get; private set; } private IDisposable _hasher; public Hasher(Hash hashType) { this.HashType = hashType; GetHasher(); } /// /// Generate the correct hashing class based on the hash type /// private void GetHasher() { switch (HashType) { case Hash.CRC: _hasher = new OptimizedCRC(); break; case Hash.MD5: _hasher = MD5.Create(); break; #if NET_FRAMEWORK case Hash.RIPEMD160: _hasher = RIPEMD160.Create(); break; #endif case Hash.SHA1: _hasher = SHA1.Create(); break; case Hash.SHA256: _hasher = SHA256.Create(); break; case Hash.SHA384: _hasher = SHA384.Create(); break; case Hash.SHA512: _hasher = SHA512.Create(); break; } } public void Dispose() { _hasher.Dispose(); } /// /// Process a buffer of some length with the internal hash algorithm /// public async Task Process(byte[] buffer, int size) { switch (HashType) { case Hash.CRC: await Task.Run(() => (_hasher as OptimizedCRC).Update(buffer, 0, size)); break; case Hash.MD5: #if NET_FRAMEWORK case Hash.RIPEMD160: #endif case Hash.SHA1: case Hash.SHA256: case Hash.SHA384: case Hash.SHA512: await Task.Run(() => (_hasher as HashAlgorithm).TransformBlock(buffer, 0, size, null, 0)); break; } } /// /// Finalize the internal hash algorigthm /// public async Task Finalize() { byte[] emptyBuffer = new byte[0]; switch (HashType) { case Hash.CRC: await Task.Run(() => (_hasher as OptimizedCRC).Update(emptyBuffer, 0, 0)); break; case Hash.MD5: #if NET_FRAMEWORK case Hash.RIPEMD160: #endif case Hash.SHA1: case Hash.SHA256: case Hash.SHA384: case Hash.SHA512: await Task.Run(() => (_hasher as HashAlgorithm).TransformFinalBlock(emptyBuffer, 0, 0)); break; } } /// /// Get internal hash as a byte array /// public byte[] GetHash() { switch (HashType) { case Hash.CRC: return BitConverter.GetBytes((_hasher as OptimizedCRC).Value).Reverse().ToArray(); case Hash.MD5: #if NET_FRAMEWORK case Hash.RIPEMD160: #endif case Hash.SHA1: case Hash.SHA256: case Hash.SHA384: case Hash.SHA512: return (_hasher as HashAlgorithm).Hash; } return null; } } }