Xor-el / HashLib4Pascal

Hashing for Modern Object Pascal
MIT License
220 stars 80 forks source link

Processing data in chunks (Are my assumptions correct)? #17

Closed maelh closed 3 years ago

maelh commented 3 years ago

I use code of the form below:

  FHasher := THashFactory.TCrypto.CreateSHA3_256();
  FHasher.Initialize;

  // repeat for each block of data (P^) where Count may vary
  FHasher.TransformUntyped(P^, Count);

  FHashResult := FHasher.TransformFinal;

Now I have several questions:

Xor-el commented 3 years ago

To answer your questions

  1. You can't modify the BlockSize (and you shouldn't) if you use the IHash instance, for BufferSize, it uses a default buffersize of 64KB but can be adjusted. Just make sure you initialize the hash instance before setting the BufferSize if you wish to adjust it.
  2. just calling initialize is fine.
  3. Always assign your constructed hash instance to an IHash variable, that way, you don't have to bother freeing the instance and can use the same variable instance for various hashers.
maelh commented 3 years ago

Thanks! Does BlockSize or BufferSize influence the size of the buffer I can pass to TransformUntyped, or is that independent?

Regarding your 3rd reply. I am using an IHash variable already, but I was wondering if recreating might be necessary, when not properly finalizing the hashing computation (as to force properly undoing/resetting things that might usually be done in TransformFinal). But I take it from your reply, that all hashers will do just fine if you just call Initialize, right?

Xor-el commented 3 years ago

BlockSize is the blocksize of the hash as defined in the hash specification, you really not need bother about that except you have a reason to. BufferSize is the chunksize of the temporary buffer used when processing streams, files or using the TransformUntyped overload. Infact, if you already have the whole byte array in memory, I suggest you use the TransformBytes overload as the TransformUntyped overload comes with with the overhead of reading the contents in chunksize of the specified BufferSize.

No need to recreate, just make sure you call Initialize before use your hash instance if you did not call TransformFinal initially. Below is a sample to clear your doubts.

FHasher := THashFactory.TCrypto.CreateSHA2_256();
FHasher.Initialize;

  // repeat for each block of data (P^) where Count may vary
  FHasher.TransformUntyped(P^, Count);

// did not call TransformFinal

  FHasher := THashFactory.TCrypto.CreateSHA3_256();
  FHasher.Initialize;

  // repeat for each block of data (P^) where Count may vary
  FHasher.TransformUntyped(P^, Count);

  FHashResult := FHasher.TransformFinal;