crypto: Streaming interface for Hash
authorisaacs <i@izs.me>
Mon, 29 Oct 2012 18:31:59 +0000 (11:31 -0700)
committerisaacs <i@izs.me>
Fri, 14 Dec 2012 18:52:26 +0000 (10:52 -0800)
lib/crypto.js
test/simple/test-crypto.js

index a787e09..8ea48e2 100644 (file)
@@ -37,6 +37,9 @@ try {
   var crypto = false;
 }
 
+var stream = require('stream');
+var util = require('util');
+
 // This is here because many functions accepted binary strings without
 // any explicit encoding in older versions of node, and we don't want
 // to break them unnecessarily.
@@ -148,12 +151,24 @@ exports.createCredentials = function(options, context) {
 
 
 exports.createHash = exports.Hash = Hash;
-function Hash(algorithm) {
+function Hash(algorithm, options) {
   if (!(this instanceof Hash))
     return new Hash(algorithm);
   this._binding = new binding.Hash(algorithm);
+  stream.Transform.call(this, options);
 }
 
+util.inherits(Hash, stream.Transform);
+
+Hash.prototype._transform = function(chunk, output, callback) {
+  this._binding.update(chunk);
+  callback();
+};
+
+Hash.prototype._flush = function(output, callback) {
+  output(this._binding.digest());
+  callback();
+};
 
 Hash.prototype.update = function(data, encoding) {
   encoding = encoding || exports.DEFAULT_ENCODING;
index 6012671..1db94a9 100644 (file)
@@ -373,6 +373,18 @@ var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
 var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
 var a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
 
+// stream interface
+var a5 = crypto.createHash('sha512');
+a5.end('Test123');
+a5 = a5.read();
+
+var a6 = crypto.createHash('sha512');
+a6.write('Te');
+a6.write('st');
+a6.write('123');
+a6.end();
+a6 = a6.read();
+
 assert.equal(a0, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
 assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
              '\u00bd\u008c', 'Test MD5 as binary');
@@ -392,6 +404,10 @@ assert.deepEqual(a4,
                  new Buffer('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'),
                  'Test SHA1');
 
+// stream interface should produce the same result.
+assert.deepEqual(a5, a3, 'stream interface is consistent');
+assert.deepEqual(a6, a3, 'stream interface is consistent');
+
 // Test multiple updates to same hash
 var h1 = crypto.createHash('sha1').update('Test123').digest('hex');
 var h2 = crypto.createHash('sha1').update('Test').update('123').digest('hex');