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
|
|
|
|
|
2020-09-04 15:02:15 -07: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
|
|
|
|
{
|
2020-06-10 22:37:19 -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;
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
2020-09-04 15:02:15 -07:00
|
|
|
|
|
|
|
|
|
|
case Hash.SpamSum:
|
|
|
|
|
|
_hasher = new SpamSumContext();
|
|
|
|
|
|
break;
|
2020-06-05 22:26:44 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
|
{
|
|
|
|
|
|
_hasher.Dispose();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-10 22:37:19 -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
|
|
|
|
{
|
|
|
|
|
|
switch (HashType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Hash.CRC:
|
2020-12-07 22:32:37 -08:00
|
|
|
|
(_hasher as OptimizedCRC.OptimizedCRC).Update(buffer, 0, size);
|
2020-06-05 22:26:44 -07:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case Hash.MD5:
|
|
|
|
|
|
case Hash.SHA1:
|
|
|
|
|
|
case Hash.SHA256:
|
|
|
|
|
|
case Hash.SHA384:
|
|
|
|
|
|
case Hash.SHA512:
|
2020-10-05 17:43:44 -07:00
|
|
|
|
(_hasher as HashAlgorithm).TransformBlock(buffer, 0, size, null, 0);
|
2020-06-05 22:26:44 -07:00
|
|
|
|
break;
|
2020-09-04 15:02:15 -07:00
|
|
|
|
|
|
|
|
|
|
case Hash.SpamSum:
|
2020-10-05 17:43:44 -07:00
|
|
|
|
(_hasher as SpamSumContext).Update(buffer);
|
2020-09-04 15:02:15 -07:00
|
|
|
|
break;
|
2020-06-05 22:26:44 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-10 22:37:19 -07:00
|
|
|
|
/// <summary>
|
2021-01-15 13:06:17 -08:00
|
|
|
|
/// Terminate the internal hash algorigthm
|
2020-06-10 22:37:19 -07:00
|
|
|
|
/// </summary>
|
2021-01-15 13:06:17 -08:00
|
|
|
|
public void Terminate()
|
2020-06-05 22:26:44 -07:00
|
|
|
|
{
|
2023-04-19 16:39:58 -04:00
|
|
|
|
byte[] emptyBuffer = Array.Empty<byte>();
|
2020-06-05 22:26:44 -07:00
|
|
|
|
switch (HashType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Hash.CRC:
|
2020-12-07 22:32:37 -08:00
|
|
|
|
(_hasher as OptimizedCRC.OptimizedCRC).Update(emptyBuffer, 0, 0);
|
2020-06-05 22:26:44 -07:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case Hash.MD5:
|
|
|
|
|
|
case Hash.SHA1:
|
|
|
|
|
|
case Hash.SHA256:
|
|
|
|
|
|
case Hash.SHA384:
|
|
|
|
|
|
case Hash.SHA512:
|
2020-10-05 17:43:44 -07:00
|
|
|
|
(_hasher as HashAlgorithm).TransformFinalBlock(emptyBuffer, 0, 0);
|
2020-06-05 22:26:44 -07:00
|
|
|
|
break;
|
2020-09-04 15:02:15 -07:00
|
|
|
|
|
|
|
|
|
|
case Hash.SpamSum:
|
|
|
|
|
|
// No finalization step needed
|
|
|
|
|
|
break;
|
2020-06-05 22:26:44 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-10 22:37:19 -07:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get internal hash as a byte array
|
|
|
|
|
|
/// </summary>
|
2020-06-05 22:26:44 -07:00
|
|
|
|
public byte[] GetHash()
|
|
|
|
|
|
{
|
2023-04-19 16:39:58 -04:00
|
|
|
|
return HashType switch
|
2020-06-05 22:26:44 -07:00
|
|
|
|
{
|
2023-04-19 16:39:58 -04:00
|
|
|
|
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,
|
|
|
|
|
|
};
|
2020-06-05 22:26:44 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|