-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reuse of createHash initializations #25857
Comments
Could you describe what it is you need, and why? Your example isn't helpful. I don't know if you want openssl style digest reuse, where after _final() the only call that can be made is an init, after which new data can be digested, or whether you want to continue on hashing new data as if the digest had not been extracted. The latter would require calling EVP_MD_CTX_copy() every time before getting the digest value, so would be prohibitively expensive. It would be possible to expose a |
Hi @sam-github ,
any loop needs reuse: const crypto = require('crypto')
const H = crypto.createHash('md5') // NEED REUSE THIS INITIALIZATION
for (let a of ["Ana Santos", "José Silva", "Bryan Lee", "Maria Silva", "Vitor Santos"])
// ... or suppose looping over 10000 items
console.log( a, H.update(a).digest("hex") ) // ugly error But the only valid (no error) syntax option is: const H = require('crypto').createHash
for (let a of ["Ana Santos", "José Silva", "Bryan Lee", "Maria Silva", "Vitor Santos"])
console.log( a, H('md5').update(a).digest("hex") )
// of course, no error, but no reuse. Please, show an example of reuse using the cited Important: there are many |
This still does not answer my question, you provide code, but no explanation of how you want the code to work.
Specifically, will iteration 2 output the hash of "José Silva", or of "Ana SantosJosé Silva"? |
@sam-github sorry, I edited with complete example... But really not understand what you show as solution. |
It appears you want iteration 2 to output the hash of "José Silva", in other words a call to
I offered no solution. Until now, I wasn't even sure what the problem was. I'll try to find some time to benchmark initialization to see what kind of performance gains are possible. Providing your own benchmarks might help motivate someone to pick this up, or you could PR the change. It seems reasonable to me. |
It would be kind of odd (in a 'no parity' sense) to have that work for hashes but not e.g. HMACs. (You could theoretically make it work for HMACs by retaining the secret but I don't think we should.) |
Differing from HMAC would be a definite downside. I notice that the openssl APIs have the ability to reuse the HASH context. I assume this is for use-cases where a HASH with some params is created, then used over and over to digest large numbers of high-throughput blocks/records/whatever, and avoid having to do a digest-init for each one. That OpenSSL does it suggests it might be useful, but whether it is relevant to any node users, or even noticable if it was done is an open question. I keep hoping someone will come up with a use-case backed by benchmarks showing that this would have a significant impact for them, but I haven't seen it yet. |
I did a quick'n'dirty benchmark to see how much time let hash = crypto.createHash('sha256');
hash.update(data);
hash.digest();
No surprises so far, the initialization time only matters for small inputs, and probably even less when dealing with strings instead of
|
Thanks @tniessen, perfect (!), now will be possible do finish this issue... after some discussion. The main justification is not performance, but something like "syntax usability enhancement", as I commented before: About performence: ok, the gain is 0 or, sometimes, greater tham zero. Is good, any gain will be a sum, a better justification, little better cost-benefit. |
@ppKrauss You have expressed your personal opinion quite strongly, both here and on StackOverflow. Please keep the discussion productive with constructive arguments instead of repeating that things are "ugly" and that "reuse makes sense". If the only benefit is "syntax usability enhancement", then consider the downsides:
|
Regarding this thread. In my code, I try to create hashes by reading different files by using createReadStream. But It is only possible to read one file. If I try to read the second file I get the error Digest already called. From the documents, I came to know that digest can be used only once. So, is there a workaround to read each file and generate corresponding hashes for each file? As @sam-github had mentioned in his previous comment-
I would like to have something like this |
@AshDee I don't understand, why don't you just create a new instance using |
Thank You @tniessen .I'll try it out... |
I'm closing this out in favor of #29903. |
@ppKrauss Love you mate. Awesome solution with that. Works GREAT for me. |
Reuse is a fundamental issue...
The problem that I am trying to solve: to reuse initialization.
The desired behavior: no error.
... No alternative solutions, but please, show me if there are some elegant one.
The text was updated successfully, but these errors were encountered: