[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