C
C#5mo ago
armoire

✅ Can't figure out a way to make TransformFinalBlock work

here's my code
public class IncrementalHasher
{
private readonly SHA1 _sha1 = SHA1.Create();

public void AddBlock(byte[] buffer, int bytesRead)
{
int writtenBytes = _sha1.TransformBlock(buffer, 0, bytesRead, null, 0);
Debugger.SendInfo(writtenBytes + " hashed");
}

public string FinalizeHash()
{
byte[] hashBytes = _sha1.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
return Convert.ToHexStringLower(hashBytes);
}
}
public class IncrementalHasher
{
private readonly SHA1 _sha1 = SHA1.Create();

public void AddBlock(byte[] buffer, int bytesRead)
{
int writtenBytes = _sha1.TransformBlock(buffer, 0, bytesRead, null, 0);
Debugger.SendInfo(writtenBytes + " hashed");
}

public string FinalizeHash()
{
byte[] hashBytes = _sha1.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
return Convert.ToHexStringLower(hashBytes);
}
}
how I use it is for a download function that needs to hash the data that is beeing downloaded in small packets, dynamically as the download goes on. I believe that is exactly what TransformBlock and TransformFinalBlock are made for. The little debug thing works for the 1st method, it does display valus that seem coherents. But the 2nd method is the issue, TransformFinalBlock returns an empty array, and that sucks. I don't set any paramaters since all of that is done with TransformBlock, and I believe TransformFinalBlock returns the hash resulting from all the blocks given to TransformBlock. So what is the issue here and how can I fix it ? Thx for any help in advance.
13 Replies
mtreit
mtreit5mo ago
Did you read the documentation for TransformFinalBlock?
armoire
armoireOP5mo ago
yes but I don't understand it
mtreit
mtreit5mo ago
Computes the hash value for the specified region of the specified byte array.
But you are passing it nothing to do any work on.
armoire
armoireOP5mo ago
then when I'm using transformBlock, how do I finalise it ?
reflectronic
reflectronic5mo ago
Note that the return value of this method is not the hash value, but only a copy of the hashed part of the input data. To retrieve the final hashed value after calling the TransformFinalBlock method, get the byte array contained in the Hash property.
mtreit
mtreit5mo ago
I believe you access the _sha1.Hash property after you call TransformFinalBlock.
reflectronic
reflectronic5mo ago
is there a reason you are not using the IncrementalHash class
mtreit
mtreit5mo ago
(Also, SHA1 is generally out of favor these days.)
armoire
armoireOP5mo ago
because I did not know how hash worked before using sha1 is necessary for my project, the server gives that king of hash the server being piston-meta.mojang.com, which is used by launchers to download minecraft not my choice so do I even need to use TransformFinalBlock then ?
mtreit
mtreit5mo ago
Sure, that's fine then. I think you do.
armoire
armoireOP5mo ago
alr thx
mtreit
mtreit5mo ago
You might also look into using the type that @reflectronic suggested: https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.incrementalhash?view=net-9.0 It might be a bit more ergonomic to use. (I've never used it myself though.)
IncrementalHash Class (System.Security.Cryptography)
Provides support for computing a hash or HMAC value incrementally across several segments.
armoire
armoireOP5mo ago
yeah it seems better how do I mark this post as solved

Did you find this page helpful?