BatchedHash.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. const MAX_SHORT_STRING = require('./wasm-hash').MAX_SHORT_STRING;
  2. class BatchedHash {
  3. constructor(hash) {
  4. this.string = undefined;
  5. this.encoding = undefined;
  6. this.hash = hash;
  7. }
  8. /**
  9. * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
  10. * @param {string|Buffer} data data
  11. * @param {string=} inputEncoding data encoding
  12. * @returns {this} updated hash
  13. */
  14. update(data, inputEncoding) {
  15. if (this.string !== undefined) {
  16. if (
  17. typeof data === 'string' &&
  18. inputEncoding === this.encoding &&
  19. this.string.length + data.length < MAX_SHORT_STRING
  20. ) {
  21. this.string += data;
  22. return this;
  23. }
  24. this.hash.update(this.string, this.encoding);
  25. this.string = undefined;
  26. }
  27. if (typeof data === 'string') {
  28. if (
  29. data.length < MAX_SHORT_STRING &&
  30. // base64 encoding is not valid since it may contain padding chars
  31. (!inputEncoding || !inputEncoding.startsWith('ba'))
  32. ) {
  33. this.string = data;
  34. this.encoding = inputEncoding;
  35. } else {
  36. this.hash.update(data, inputEncoding);
  37. }
  38. } else {
  39. this.hash.update(data);
  40. }
  41. return this;
  42. }
  43. /**
  44. * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
  45. * @param {string=} encoding encoding of the return value
  46. * @returns {string|Buffer} digest
  47. */
  48. digest(encoding) {
  49. if (this.string !== undefined) {
  50. this.hash.update(this.string, this.encoding);
  51. }
  52. return this.hash.digest(encoding);
  53. }
  54. }
  55. module.exports = BatchedHash;