Files
SabreTools/SabreTools.Core/Tools/Hasher.cs

165 lines
4.4 KiB
C#
Raw Normal View History

2020-06-05 22:26:44 -07:00
using System;
using System.Linq;
using System.Security.Cryptography;
2020-12-07 12:33:24 -08:00
using Aaru.Checksums;
2020-06-05 22:26:44 -07:00
2020-12-10 22:16:53 -08:00
namespace SabreTools.Core.Tools
2020-06-05 22:26:44 -07:00
{
/// <summary>
/// Async hashing class wraper
/// </summary>
2020-06-05 22:26:44 -07:00
public class Hasher
{
public Hash HashType { get; private set; }
private IDisposable? _hasher;
2020-06-05 22:26:44 -07:00
public Hasher(Hash hashType)
{
this.HashType = hashType;
GetHasher();
}
/// <summary>
/// Generate the correct hashing class based on the hash type
/// </summary>
private void GetHasher()
{
switch (HashType)
{
case Hash.CRC:
2020-12-07 22:32:37 -08:00
_hasher = new OptimizedCRC.OptimizedCRC();
2020-06-05 22:26:44 -07:00
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;
2020-06-05 22:26:44 -07:00
}
}
public void Dispose()
{
_hasher?.Dispose();
2020-06-05 22:26:44 -07:00
}
/// <summary>
/// Process a buffer of some length with the internal hash algorithm
/// </summary>
2020-10-05 17:43:44 -07:00
public void Process(byte[] buffer, int size)
2020-06-05 22:26:44 -07:00
{
if (_hasher == null)
return;
switch (_hasher)
2020-06-05 22:26:44 -07:00
{
case OptimizedCRC.OptimizedCRC crc:
crc.Update(buffer, 0, size);
2020-06-05 22:26:44 -07:00
break;
case MD5 md5:
md5.TransformBlock(buffer, 0, size, null, 0);
2020-06-05 22:26:44 -07:00
break;
case SHA1 sha1:
sha1.TransformBlock(buffer, 0, size, null, 0);
break;
case SHA256 sha256:
sha256.TransformBlock(buffer, 0, size, null, 0);
break;
case SHA384 sha384:
sha384.TransformBlock(buffer, 0, size, null, 0);
break;
case SHA512 sha512:
sha512.TransformBlock(buffer, 0, size, null, 0);
break;
case SpamSumContext spamSum:
spamSum.Update(buffer);
break;
2020-06-05 22:26:44 -07:00
}
}
/// <summary>
2021-01-15 13:06:17 -08:00
/// Terminate the internal hash algorigthm
/// </summary>
2021-01-15 13:06:17 -08:00
public void Terminate()
2020-06-05 22:26:44 -07:00
{
if (_hasher == null)
return;
byte[] emptyBuffer = Array.Empty<byte>();
switch (_hasher)
2020-06-05 22:26:44 -07:00
{
case OptimizedCRC.OptimizedCRC crc:
crc.Update(emptyBuffer, 0, 0);
2020-06-05 22:26:44 -07:00
break;
case MD5 md5:
md5.TransformFinalBlock(emptyBuffer, 0, 0);
2020-06-05 22:26:44 -07:00
break;
case SHA1 sha1:
sha1.TransformFinalBlock(emptyBuffer, 0, 0);
break;
case SHA256 sha256:
sha256.TransformFinalBlock(emptyBuffer, 0, 0);
break;
case SHA384 sha384:
sha384.TransformFinalBlock(emptyBuffer, 0, 0);
break;
case SHA512 sha512:
sha512.TransformFinalBlock(emptyBuffer, 0, 0);
break;
case SpamSumContext:
// No finalization step needed
break;
2020-06-05 22:26:44 -07:00
}
}
/// <summary>
/// Get internal hash as a byte array
/// </summary>
public byte[]? GetHash()
2020-06-05 22:26:44 -07:00
{
return _hasher switch
2020-06-05 22:26:44 -07:00
{
OptimizedCRC.OptimizedCRC crc => BitConverter.GetBytes(crc.Value).Reverse().ToArray(),
MD5 md5 => md5.Hash,
SHA1 sha1 => sha1.Hash,
SHA256 sha256 => sha256.Hash,
SHA384 sha384 => sha384.Hash,
SHA512 sha512 => sha512.Hash,
SpamSumContext spamSum => spamSum.Final(),
_ => null,
};
2020-06-05 22:26:44 -07:00
}
}
}