diff --git a/DotVast.HashTool.WinUI/DotVast.HashTool.WinUI.csproj b/DotVast.HashTool.WinUI/DotVast.HashTool.WinUI.csproj
index 948306c..ff86e76 100644
--- a/DotVast.HashTool.WinUI/DotVast.HashTool.WinUI.csproj
+++ b/DotVast.HashTool.WinUI/DotVast.HashTool.WinUI.csproj
@@ -57,6 +57,7 @@
+
diff --git a/DotVast.HashTool.WinUI/Models/Hash.cs b/DotVast.HashTool.WinUI/Enums/Hash.cs
similarity index 51%
rename from DotVast.HashTool.WinUI/Models/Hash.cs
rename to DotVast.HashTool.WinUI/Enums/Hash.cs
index 9941d95..d9323a8 100644
--- a/DotVast.HashTool.WinUI/Models/Hash.cs
+++ b/DotVast.HashTool.WinUI/Enums/Hash.cs
@@ -13,7 +13,7 @@
using Crypto = System.Security.Cryptography;
-namespace DotVast.HashTool.WinUI.Models;
+namespace DotVast.HashTool.WinUI.Enums;
[JsonConverter(typeof(JsonConverterFactoryForGenericEnumDerived))]
public sealed class Hash : GenericEnum
@@ -73,6 +73,10 @@ public sealed class Hash : GenericEnum
public static readonly Hash Keccak_384 = new("Keccak-384");
public static readonly Hash Keccak_512 = new("Keccak-512");
+ // xxHash
+ public static readonly Hash XxHash32 = new("xxHash32");
+ public static readonly Hash XxHash64 = new("xxHash64");
+
// QuickXor
public static readonly Hash QuickXor = new("QuickXor");
@@ -87,38 +91,40 @@ private Hash(string name) : base(name)
{
return hash switch
{
- var h when h == Hash.CRC32 => CreateCRC(CRCModel.CRC32).ToHashAlgorithm(),
- var h when h == Hash.MD4 => CreateMD4().ToHashAlgorithm(),
- var h when h == Hash.MD5 => Crypto.MD5.Create(),
- var h when h == Hash.SHA1 => Crypto.SHA1.Create(),
- var h when h == Hash.SHA224 => CreateSHA2_224().ToHashAlgorithm(),
- var h when h == Hash.SHA256 => Crypto.SHA256.Create(),
- var h when h == Hash.SHA384 => Crypto.SHA384.Create(),
- var h when h == Hash.SHA512 => Crypto.SHA512.Create(),
- var h when h == Hash.SHA3_224 => CreateSHA3_224().ToHashAlgorithm(),
- var h when h == Hash.SHA3_256 => CreateSHA3_256().ToHashAlgorithm(),
- var h when h == Hash.SHA3_384 => CreateSHA3_384().ToHashAlgorithm(),
- var h when h == Hash.SHA3_512 => CreateSHA3_512().ToHashAlgorithm(),
- var h when h == Hash.SM3 => new SM3Digest().ToHashAlgorithm(),
- var h when h == Hash.Blake2B_160 => CreateBlake2B_160().ToHashAlgorithm(),
- var h when h == Hash.Blake2B_256 => CreateBlake2B_256().ToHashAlgorithm(),
- var h when h == Hash.Blake2B_384 => CreateBlake2B_384().ToHashAlgorithm(),
- var h when h == Hash.Blake2B_512 => CreateBlake2B_512().ToHashAlgorithm(),
- var h when h == Hash.Blake2S_128 => CreateBlake2S_128().ToHashAlgorithm(),
- var h when h == Hash.Blake2S_160 => CreateBlake2S_160().ToHashAlgorithm(),
- var h when h == Hash.Blake2S_224 => CreateBlake2S_224().ToHashAlgorithm(),
- var h when h == Hash.Blake2S_256 => CreateBlake2S_256().ToHashAlgorithm(),
- var h when h == Hash.Blake3 => CreateBlake3_256().ToHashAlgorithm(),
- var h when h == Hash.RIPEMD128 => CreateRIPEMD128().ToHashAlgorithm(),
- var h when h == Hash.RIPEMD160 => CreateRIPEMD160().ToHashAlgorithm(),
- var h when h == Hash.RIPEMD256 => CreateRIPEMD256().ToHashAlgorithm(),
- var h when h == Hash.RIPEMD320 => CreateRIPEMD320().ToHashAlgorithm(),
- var h when h == Hash.Keccak_224 => CreateKeccak_224().ToHashAlgorithm(),
- var h when h == Hash.Keccak_256 => CreateKeccak_256().ToHashAlgorithm(),
- var h when h == Hash.Keccak_288 => CreateKeccak_288().ToHashAlgorithm(),
- var h when h == Hash.Keccak_384 => CreateKeccak_384().ToHashAlgorithm(),
- var h when h == Hash.Keccak_512 => CreateKeccak_512().ToHashAlgorithm(),
- var h when h == Hash.QuickXor => new QuickXorHash(),
+ var h when h == CRC32 => CreateCRC(CRCModel.CRC32).ToHashAlgorithm(),
+ var h when h == MD4 => CreateMD4().ToHashAlgorithm(),
+ var h when h == MD5 => Crypto.MD5.Create(),
+ var h when h == SHA1 => Crypto.SHA1.Create(),
+ var h when h == SHA224 => CreateSHA2_224().ToHashAlgorithm(),
+ var h when h == SHA256 => Crypto.SHA256.Create(),
+ var h when h == SHA384 => Crypto.SHA384.Create(),
+ var h when h == SHA512 => Crypto.SHA512.Create(),
+ var h when h == SHA3_224 => CreateSHA3_224().ToHashAlgorithm(),
+ var h when h == SHA3_256 => CreateSHA3_256().ToHashAlgorithm(),
+ var h when h == SHA3_384 => CreateSHA3_384().ToHashAlgorithm(),
+ var h when h == SHA3_512 => CreateSHA3_512().ToHashAlgorithm(),
+ var h when h == SM3 => new SM3Digest().ToHashAlgorithm(),
+ var h when h == Blake2B_160 => CreateBlake2B_160().ToHashAlgorithm(),
+ var h when h == Blake2B_256 => CreateBlake2B_256().ToHashAlgorithm(),
+ var h when h == Blake2B_384 => CreateBlake2B_384().ToHashAlgorithm(),
+ var h when h == Blake2B_512 => CreateBlake2B_512().ToHashAlgorithm(),
+ var h when h == Blake2S_128 => CreateBlake2S_128().ToHashAlgorithm(),
+ var h when h == Blake2S_160 => CreateBlake2S_160().ToHashAlgorithm(),
+ var h when h == Blake2S_224 => CreateBlake2S_224().ToHashAlgorithm(),
+ var h when h == Blake2S_256 => CreateBlake2S_256().ToHashAlgorithm(),
+ var h when h == Blake3 => CreateBlake3_256().ToHashAlgorithm(),
+ var h when h == RIPEMD128 => CreateRIPEMD128().ToHashAlgorithm(),
+ var h when h == RIPEMD160 => CreateRIPEMD160().ToHashAlgorithm(),
+ var h when h == RIPEMD256 => CreateRIPEMD256().ToHashAlgorithm(),
+ var h when h == RIPEMD320 => CreateRIPEMD320().ToHashAlgorithm(),
+ var h when h == Keccak_224 => CreateKeccak_224().ToHashAlgorithm(),
+ var h when h == Keccak_256 => CreateKeccak_256().ToHashAlgorithm(),
+ var h when h == Keccak_288 => CreateKeccak_288().ToHashAlgorithm(),
+ var h when h == Keccak_384 => CreateKeccak_384().ToHashAlgorithm(),
+ var h when h == Keccak_512 => CreateKeccak_512().ToHashAlgorithm(),
+ var h when h == XxHash32 => new System.IO.Hashing.XxHash32().ToHashAlgorithm(),
+ var h when h == XxHash64 => new System.IO.Hashing.XxHash64().ToHashAlgorithm(),
+ var h when h == QuickXor => new QuickXorHash(),
_ => null,
};
}
diff --git a/DotVast.HashTool.WinUI/Helpers/Hashes/NonCryptographicHashAlgorithmAdapter.cs b/DotVast.HashTool.WinUI/Helpers/Hashes/NonCryptographicHashAlgorithmAdapter.cs
new file mode 100644
index 0000000..5d4aa6f
--- /dev/null
+++ b/DotVast.HashTool.WinUI/Helpers/Hashes/NonCryptographicHashAlgorithmAdapter.cs
@@ -0,0 +1,30 @@
+using System.IO.Hashing;
+using System.Security.Cryptography;
+
+namespace DotVast.HashTool.WinUI.Helpers.Hashes;
+
+internal static class NonCryptographicHashAlgorithmAdapterExtensions
+{
+ public static HashAlgorithm ToHashAlgorithm(this NonCryptographicHashAlgorithm hash) =>
+ new NonCryptographicHashAlgorithmAdapter(hash);
+}
+
+sealed file class NonCryptographicHashAlgorithmAdapter : HashAlgorithm
+{
+ private readonly NonCryptographicHashAlgorithm _hash;
+
+ public NonCryptographicHashAlgorithmAdapter(NonCryptographicHashAlgorithm hash)
+ {
+ _hash = hash;
+ HashSizeValue = hash.HashLengthInBytes * 8;
+ }
+
+ public override void Initialize() =>
+ _hash.Reset();
+
+ protected override void HashCore(byte[] array, int ibStart, int cbSize) =>
+ _hash.Append(array.AsSpan(ibStart, cbSize));
+
+ protected override byte[] HashFinal() =>
+ _hash.GetCurrentHash();
+}
diff --git a/DotVast.HashTool.WinUI/Models/HashOption.cs b/DotVast.HashTool.WinUI/Models/HashOption.cs
index 3200754..43d7045 100644
--- a/DotVast.HashTool.WinUI/Models/HashOption.cs
+++ b/DotVast.HashTool.WinUI/Models/HashOption.cs
@@ -1,3 +1,5 @@
+using DotVast.HashTool.WinUI.Enums;
+
namespace DotVast.HashTool.WinUI.Models;
public sealed partial class HashOption : ObservableRecipient
diff --git a/DotVast.HashTool.WinUI/Services/Settings/PreferencesSettingsService.cs b/DotVast.HashTool.WinUI/Services/Settings/PreferencesSettingsService.cs
index 40c1c19..58b18e5 100644
--- a/DotVast.HashTool.WinUI/Services/Settings/PreferencesSettingsService.cs
+++ b/DotVast.HashTool.WinUI/Services/Settings/PreferencesSettingsService.cs
@@ -2,6 +2,7 @@
using DotVast.HashTool.WinUI.Contracts.Services.Settings;
using DotVast.HashTool.WinUI.Core.Enums;
+using DotVast.HashTool.WinUI.Enums;
using DotVast.HashTool.WinUI.Models;
using static DotVast.HashTool.WinUI.Constants;
diff --git a/DotVast.HashTool.WinUI/ViewModels/LicensesViewModel.cs b/DotVast.HashTool.WinUI/ViewModels/LicensesViewModel.cs
index 4ac5399..3720887 100644
--- a/DotVast.HashTool.WinUI/ViewModels/LicensesViewModel.cs
+++ b/DotVast.HashTool.WinUI/ViewModels/LicensesViewModel.cs
@@ -25,6 +25,8 @@ public sealed partial class LicensesViewModel : ObservableRecipient
new("Serilog.Extensions.Hosting", License.Apache_2_0, NugetLicenseUrl.Apache_2_0,"https://www.nuget.org/packages/Serilog.Extensions.Hosting"),
new("Serilog.Sinks.File", License.Apache_2_0, NugetLicenseUrl.Apache_2_0,"https://www.nuget.org/packages/Serilog.Sinks.File"),
+ new("System.IO.Hashing", License.MIT, NugetLicenseUrl.MIT, "https://www.nuget.org/packages/System.IO.Hashing"),
+
new("WinUIEx", License.Apache_2_0, NugetLicenseUrl.Apache_2_0,"https://www.nuget.org/packages/WinUIEx"),
new("QuickXorHash.cs", License.MIT, "https://gist.github.com/rgregg/c07a91964300315c6c3e77f7b5b861e4","https://gist.github.com/rgregg/c07a91964300315c6c3e77f7b5b861e4"),