[Pkg-javascript-commits] [node-hash-base] 04/06: Add blocks handling

Bastien Roucariès rouca at moszumanska.debian.org
Thu May 4 10:21:23 UTC 2017


This is an automated email from the git hooks/post-receive script.

rouca pushed a commit to annotated tag v2.0.0
in repository node-hash-base.

commit 0c8fb676e7d15af1fb7d441a7b9d783c17da5d08
Author: Kirill Fomichev <fanatid at ya.ru>
Date:   Thu Apr 7 09:36:43 2016 +0300

    Add blocks handling
---
 README.md     | 20 +++++++++++++++++---
 index.js      | 31 ++++++++++++++++++++++++++++---
 test/index.js | 55 +++++++++++++++++++++++++++++++------------------------
 3 files changed, 76 insertions(+), 30 deletions(-)

diff --git a/README.md b/README.md
index 38dbc88..2fa8f1d 100644
--- a/README.md
+++ b/README.md
@@ -8,11 +8,24 @@
 
 Abstract base class to inherit from if you want to create streams implementing the same API as node crypto [Hash][1] (for [Cipher][2] / [Decipher][3] check [crypto-browserify/cipher-base][4]).
 
-Requires you to implement 2 methods:
+## Example
 
-  - `_update(data)` takes a buffer and should return nothing
+```js
+function MyHash () {
+  HashBase.call(64) // in bytes
+}
 
-  - `_digest()` takes no arguments and should return a buffer
+inherti(MyHash, HashBase)
+
+MyHash.prototype._update = function () {
+  // hashing one block with buffer this._block
+}
+
+MyHash.prototype._digest = function () {
+  // create padding and produce result
+}
+```
+You also can check [source code](index.js) or [crypto-browserify/md5.js][5]
 
 ## LICENSE
 
@@ -22,3 +35,4 @@ MIT
 [2]: https://nodejs.org/api/crypto.html#crypto_class_cipher
 [3]: https://nodejs.org/api/crypto.html#crypto_class_decipher
 [4]: https://github.com/crypto-browserify/cipher-base
+[5]: https://github.com/crypto-browserify/md5.js
diff --git a/index.js b/index.js
index a73ecc2..64a6b09 100644
--- a/index.js
+++ b/index.js
@@ -2,8 +2,14 @@
 var Transform = require('stream').Transform
 var inherits = require('inherits')
 
-function HashBase () {
+function HashBase (blockSize) {
   Transform.call(this)
+
+  this._block = new Buffer(blockSize)
+  this._blockSize = blockSize
+  this._blockOffset = 0
+  this._length = [0, 0, 0, 0]
+
   this._finalized = false
 }
 
@@ -12,7 +18,26 @@ inherits(HashBase, Transform)
 HashBase.prototype.update = function (data, encoding) {
   if (this._finalized) throw new Error('Digest already called')
   if (!Buffer.isBuffer(data)) data = new Buffer(data, encoding || 'binary')
-  this._update(data)
+
+  // consume data
+  var offset = 0
+  while (this._blockOffset + data.length - offset >= this._blockSize) {
+    for (var i = this._blockOffset; i < this._blockSize;) this._block[i++] = data[offset++]
+    this._update()
+    this._blockOffset = 0
+  }
+
+  while (offset < data.length) {
+    this._block[this._blockOffset++] = data[offset++]
+  }
+
+  // update length
+  for (var i = 0, carry = data.length * 8; carry > 0; ++i) {
+    this._length[i] += carry
+    carry = Math.floor(this._length[i] / 0x0100000000)
+    if (carry > 0) this._length[i] -= 0x0100000000 * carry
+  }
+
   return this
 }
 
@@ -37,7 +62,7 @@ HashBase.prototype._transform = function (chunk, encoding, callback) {
   var error = null
   try {
     if (encoding !== 'buffer') chunk = new Buffer(chunk, encoding)
-    this._update(chunk)
+    this.update(chunk)
   } catch (err) {
     error = err
   }
diff --git a/test/index.js b/test/index.js
index cc4e925..e6a17f4 100644
--- a/test/index.js
+++ b/test/index.js
@@ -6,7 +6,7 @@ function beforeEach (t) {
   var _test = t.test
   t.test = function (name, cb) {
     _test(name, function (t) {
-      t.base = new HashBase()
+      t.base = new HashBase(64)
       cb(t)
     })
   }
@@ -16,33 +16,40 @@ test('update', function (t) {
   beforeEach(t)
 
   t.test('should return hash instance', function (t) {
-    t.base._update = function () {}
-    t.same(t.base.update(new Buffer(42)), t.base)
+    t.same(t.base.update(new Buffer(63)), t.base)
     t.end()
   })
 
-  t.test('should pass buffer to _update', function (t) {
+  t.test('decode string with custom encoding', function (t) {
     t.plan(1)
-    var buffer = new Buffer(42)
-    t.base._update = function (data) { t.true(buffer === data) }
-    t.base.update(buffer)
+    var buffer = new Buffer('УТФ-8 text', 'utf-8')
+    var base = new HashBase(buffer.length)
+    base._update = function () { t.same(this._block, buffer) }
+    base.update(buffer.toString('utf-8'), 'utf-8')
     t.end()
   })
 
-  t.test('should decode string as binary by default', function (t) {
-    t.base._update = function (data) { t.same(data, new Buffer('ZЪ', 'binary')) }
-    t.base.update('ZЪ')
+  t.test('decode string with binary by default', function (t) {
+    t.plan(1)
+    var buffer = new Buffer(64)
+    t.base._update = function () { t.same(this._block, buffer) }
+    t.base.update(buffer.toString('binary'))
     t.end()
   })
 
-  t.test('should decode string with custom encoding', function (t) {
-    t.base._update = function (data) { t.same(data, new Buffer('ZЪ', 'utf-8')) }
-    t.base.update('ZЪ', 'utf-8')
+  t.test('data length is more than 2^32', function (t) {
+    t.plan(3)
+    var buffer = new Buffer(1048576)
+    var base = new HashBase(1048576)
+    base._length = [ 4286578688, 0, 0, 0 ]
+    base._update = function () { t.same(this._block, buffer) }
+    base.update(buffer)
+    base.update(buffer)
+    t.same(base._length, [ 8388608, 1, 0, 0 ])
     t.end()
   })
 
   t.test('call after digest should throw error', function (t) {
-    t.base._update = function () {}
     t.base._digest = function () {}
     t.base.digest()
     t.throws(function () {
@@ -69,14 +76,14 @@ test('digest', function (t) {
   })
 
   t.test('should return buffer by default', function (t) {
-    t.base._digest = function () { return new Buffer('ZЪ', 'utf-8') }
-    t.same(t.base.digest(), new Buffer('ZЪ', 'utf-8'))
+    t.base._digest = function () { return new Buffer('УТФ-8 text', 'utf-8') }
+    t.same(t.base.digest(), new Buffer('УТФ-8 text', 'utf-8'))
     t.end()
   })
 
   t.test('should encode result with custom encoding', function (t) {
-    t.base._digest = function () { return new Buffer('ZЪ', 'utf-8') }
-    t.same(t.base.digest('utf-8'), 'ZЪ')
+    t.base._digest = function () { return new Buffer('УТФ-8 text', 'utf-8') }
+    t.same(t.base.digest('utf-8'), 'УТФ-8 text')
     t.end()
   })
 
@@ -121,10 +128,10 @@ test('_digest', function (t) {
 test('_transform', function (t) {
   beforeEach(t)
 
-  t.test('should use _update', function (t) {
+  t.test('should use update', function (t) {
     t.plan(2)
     var buffer = new Buffer(42)
-    t.base._update = function (data) { t.true(data === buffer) }
+    t.base.update = function (data) { t.true(data === buffer) }
     t.base._transform(buffer, 'buffer', function (err) {
       t.same(err, null)
     })
@@ -133,17 +140,17 @@ test('_transform', function (t) {
 
   t.test('should decode string with custom encoding', function (t) {
     t.plan(2)
-    t.base._update = function (data) { t.same(data, new Buffer('ZЪ', 'utf-8')) }
-    t.base._transform('ZЪ', 'utf-8', function (err) {
+    t.base.update = function (data) { t.same(data, new Buffer('УТФ-8 text', 'utf-8')) }
+    t.base._transform('УТФ-8 text', 'utf-8', function (err) {
       t.same(err, null)
     })
     t.end()
   })
 
-  t.test('should handle error in _update', function (t) {
+  t.test('should handle error in update', function (t) {
     t.plan(1)
     var err = new Error('hey')
-    t.base._update = function () { throw err }
+    t.base.update = function () { throw err }
     t.base._transform(new Buffer(42), 'buffer', function (_err) {
       t.true(_err === err)
     })

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-hash-base.git



More information about the Pkg-javascript-commits mailing list