Skip to content

Commit 7177c5a

Browse files
authored
Refactor HashAlgorithmWrapper_Implementation class
Signed-off-by: Xen <lordofxen@deskasoft.com>
1 parent 7ed7bc6 commit 7177c5a

File tree

1 file changed

+50
-20
lines changed

1 file changed

+50
-20
lines changed

HashifyNet/Core/HashAlgorithmWrapper/HashAlgorithmWrapper_Implementation.cs

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,18 @@
2929

3030
using HashifyNet.Core.Utilities;
3131
using System;
32-
using System.IO;
3332
using System.Threading;
3433

3534
namespace HashifyNet.Core.HashAlgorithm
3635
{
37-
[HashAlgorithmImplementation(typeof(IHashAlgorithmWrapper), typeof(HashAlgorithmWrapperConfig))]
3836
internal class HashAlgorithmWrapper_Implementation
39-
: CryptographicHashFunctionBase<IHashAlgorithmWrapperConfig>,
37+
: CryptographicStreamableHashFunctionBase<IHashAlgorithmWrapperConfig>,
4038
IHashAlgorithmWrapper
4139
{
4240
public override IHashAlgorithmWrapperConfig Config => _config.Clone();
4341

4442
private readonly IHashAlgorithmWrapperConfig _config;
43+
private readonly System.Security.Cryptography.HashAlgorithm hashAlgorithm;
4544
public HashAlgorithmWrapper_Implementation(IHashAlgorithmWrapperConfig config)
4645
{
4746
if (config == null)
@@ -52,37 +51,68 @@ public HashAlgorithmWrapper_Implementation(IHashAlgorithmWrapperConfig config)
5251
_config = config.Clone();
5352
if (_config.InstanceFactory == null)
5453
{
55-
throw new ArgumentException($"{nameof(config)}.{nameof(config.InstanceFactory)} has not been set.", $"{nameof(config)}.{nameof(config.InstanceFactory)}");
54+
throw new ArgumentException($"{nameof(_config)}.{nameof(_config.InstanceFactory)} has not been set.", $"{nameof(_config)}.{nameof(_config.InstanceFactory)}");
5655
}
5756

58-
using (var hashAlgorithm = _config.InstanceFactory())
57+
hashAlgorithm = _config.InstanceFactory() ?? throw new InvalidOperationException("The hash algorithm factory returned null.");
58+
59+
if (_config.HashSizeInBits != hashAlgorithm.HashSize)
5960
{
60-
if (_config.HashSizeInBits != hashAlgorithm.HashSize)
61-
{
62-
throw new InvalidOperationException($"{nameof(config)}.{nameof(config.HashSizeInBits)} does not match the underlying {nameof(config.InstanceFactory)} hash algorithm's size. Expected {config.HashSizeInBits} bits but got {hashAlgorithm.HashSize} bits.");
63-
}
61+
throw new InvalidOperationException($"{nameof(_config)}.{nameof(_config.HashSizeInBits)} does not match the underlying {nameof(_config.InstanceFactory)} hash algorithm's size. Expected {_config.HashSizeInBits} bits but got {hashAlgorithm.HashSize} bits.");
6462
}
6563
}
6664

67-
public IHashValue ComputeHash(Stream data)
65+
public override IBlockTransformer CreateBlockTransformer()
6866
{
69-
using (var hashAlgorithm = _config.InstanceFactory())
67+
return new BlockTransformer(hashAlgorithm);
68+
}
69+
70+
protected override void Dispose(bool disposing)
71+
{
72+
if (disposing)
7073
{
71-
return new HashValue(
72-
hashAlgorithm.ComputeHash(data),
73-
_config.HashSizeInBits);
74+
hashAlgorithm?.Dispose();
7475
}
76+
77+
base.Dispose(disposing);
7578
}
7679

77-
protected override IHashValue ComputeHashInternal(ArraySegment<byte> data, CancellationToken cancellationToken)
80+
private class BlockTransformer : BlockTransformerBase<BlockTransformer>
7881
{
79-
using (var hashAlgorithm = _config.InstanceFactory())
82+
public BlockTransformer()
83+
{
84+
}
85+
86+
private System.Security.Cryptography.HashAlgorithm _algo;
87+
public BlockTransformer(System.Security.Cryptography.HashAlgorithm algorithm) : this()
88+
{
89+
_algo = algorithm ?? throw new ArgumentNullException(nameof(algorithm));
90+
}
91+
92+
protected override void CopyStateTo(BlockTransformer other)
8093
{
81-
return new HashValue(
82-
hashAlgorithm.ComputeHash(data.Array, data.Offset, data.Count),
83-
_config.HashSizeInBits);
94+
other._algo = _algo;
95+
}
96+
97+
protected override void TransformByteGroupsInternal(ArraySegment<byte> data)
98+
{
99+
if (_algo.TransformBlock(data.Array, data.Offset, data.Count, null, 0) != data.Count)
100+
{
101+
throw new Exception("Hash algorithm did not process all input data.");
102+
}
103+
}
104+
105+
protected override IHashValue FinalizeHashValueInternal(CancellationToken cancellationToken)
106+
{
107+
byte[] lastBytes = FinalizeInputBuffer ?? Array.Empty<byte>();
108+
byte[] lastResult = _algo.TransformFinalBlock(lastBytes, 0, lastBytes.Length);
109+
if (lastResult == null || lastResult.Length != lastBytes.Length)
110+
{
111+
throw new Exception("Hash algorithm did not process all input data.");
112+
}
113+
114+
return new HashValue(_algo.Hash, _algo.HashSize);
84115
}
85116
}
86117
}
87-
88118
}

0 commit comments

Comments
 (0)