Prabhat Prabhat - 3 months ago 33
Node.js Question

Nodejs crypto md5 hash gives me digest of size 24 bytes, instead of expected 16

var crypto = require('crypto');
var key1 = crypto.createHash('md5').update('abcdefgh').digest();
var key2 = crypto.createHash('md5').update('abcdefgh').digest('base64');
var key3 = crypto.createHash('md5').update('abcdefgh').digest('hex');
var key4 = crypto.createHash('md5').update('abcdefgh').digest('latin1');
console.log('Key sizes :', key1.toString().length, key2.toString().length, key3.toString().length, key4.toString().length );
//Key sizes : 16 24 32 16


Doesn't md5 supposed to return 16 byte digest always?

Answer

hash.digest(encoding) docs

Calculates the digest of all of the data passed to be hashed (using the hash.update() method). The encoding can be 'hex', 'latin1' or 'base64'. If encoding is provided a string will be returned; otherwise a Buffer is returned.

'binary' is not a recognized type of encoding for digest. By default an encoding of type 'buffer' is used.

Instead, use 'hex' or 'base64'

var key1 = crypto.createHash('md5').update('abcdefgh').digest('hex');

key1.length
// => 16

key1.toString()
// => 'e8dc4081b13434b45189a720b77b6818'

Note the output is 32 chars, where each 2 chars represents a single byte in hex format.

So the hash size is actually (32/2=16) 16 bytes.


binary output is self explanatory, no encoding

Well no, it's not self-explanatory. It's an undocumented parameter value. But, notice tho that encoding is an optional parameter.

If you don't use an argument when calling digest, you still get a 16-byte result

var key1 = crypto.createHash('md5').update('abcdefgh').digest()

key1.length
// => 16

key1.toString()
// => '��@��44�Q�� �{h\u0018'

key1.toString().length
// => 16

Note that when the 'buffer' type is used, the default encoding for a Buffer is 'utf8'. So when we call buffer.toString we get this nasty output. Do you see the \u in there? That's unicode. You can easily convert the buffer to a hex string (or base64) if you didn't use the proper digest argument, tho

// digest defaults to 'buffer' for unrecognized type
var key1 = crypto.createHash('md5').update('abcdefgh').digest('
Comments