using System;
using System.Linq;
using System.Security.Cryptography;
using Aaru.Checksums;
namespace SabreTools.Core.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.OptimizedCRC();
break;
case Hash.MD5:
_hasher = MD5.Create();
break;
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;
case Hash.SpamSum:
_hasher = new SpamSumContext();
break;
}
}
public void Dispose()
{
_hasher.Dispose();
}
///
/// Process a buffer of some length with the internal hash algorithm
///
public void Process(byte[] buffer, int size)
{
switch (HashType)
{
case Hash.CRC:
(_hasher as OptimizedCRC.OptimizedCRC).Update(buffer, 0, size);
break;
case Hash.MD5:
case Hash.SHA1:
case Hash.SHA256:
case Hash.SHA384:
case Hash.SHA512:
(_hasher as HashAlgorithm).TransformBlock(buffer, 0, size, null, 0);
break;
case Hash.SpamSum:
(_hasher as SpamSumContext).Update(buffer);
break;
}
}
///
/// Terminate the internal hash algorigthm
///
public void Terminate()
{
byte[] emptyBuffer = Array.Empty();
switch (HashType)
{
case Hash.CRC:
(_hasher as OptimizedCRC.OptimizedCRC).Update(emptyBuffer, 0, 0);
break;
case Hash.MD5:
case Hash.SHA1:
case Hash.SHA256:
case Hash.SHA384:
case Hash.SHA512:
(_hasher as HashAlgorithm).TransformFinalBlock(emptyBuffer, 0, 0);
break;
case Hash.SpamSum:
// No finalization step needed
break;
}
}
///
/// Get internal hash as a byte array
///
public byte[] GetHash()
{
return HashType switch
{
Hash.CRC => BitConverter.GetBytes((_hasher as OptimizedCRC.OptimizedCRC).Value).Reverse().ToArray(),
Hash.MD5 => (_hasher as HashAlgorithm).Hash,
Hash.SHA1 => (_hasher as HashAlgorithm).Hash,
Hash.SHA256 => (_hasher as HashAlgorithm).Hash,
Hash.SHA384 => (_hasher as HashAlgorithm).Hash,
Hash.SHA512 => (_hasher as HashAlgorithm).Hash,
Hash.SpamSum => (_hasher as SpamSumContext).Final(),
_ => null,
};
}
}
}