Nodejs crypto md5 hash 给了我 24 字节的摘要,而不是预期的 16
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
md5 不应该总是 return 16 字节摘要吗?
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'
不是 digest
的可识别编码类型。默认情况下使用 'buffer'
类型的编码。
而是使用 'hex'
或 'base64'
var key1 = crypto.createHash('md5').update('abcdefgh').digest('hex');
key1.length
// => 16
key1.toString()
// => 'e8dc4081b13434b45189a720b77b6818'
注意输出是 32 个字符,其中每 2 个字符代表一个十六进制格式的字节。
所以哈希大小实际上是 (32/2=16) 16 字节.
binary
output is self explanatory, no encoding
嗯,不,这不是不言自明的。这是一个未记录的参数值。但是,请注意 encoding
是一个 可选的 参数。
如果在调用 digest
时不使用参数,您仍然会得到 16 字节的结果
var key1 = crypto.createHash('md5').update('abcdefgh').digest()
key1.length
// => 16
key1.toString()
// => '��@��44�Q�� �{h\u0018'
key1.toString().length
// => 16
请注意,当使用 'buffer'
类型时,Buffer
的默认编码是 'utf8'
。所以当我们调用 buffer.toString
时,我们得到了这个讨厌的输出。你看到里面的 \u
了吗?那是统一码。如果您没有使用正确的 digest
参数,您可以轻松地将缓冲区转换为 hex
字符串(或 base64
),
// digest defaults to 'buffer' for unrecognized type
var key1 = crypto.createHash('md5').update('abcdefgh').digest('')
key1.length
// => 16
key1.toString()
// => '��@��44�Q�� �{h\u0018'
key1.toString('hex')
// => 'e8dc4081b13434b45189a720b77b6818'
无论传递给摘要的参数如何,缓冲区中的结果字节都是相同的。编码只是传递给缓冲区,只要您选择将缓冲区转换为字符串,就可以更改编码。
Buffer 构造函数(已弃用)需要第二个编码参数。如果您不指定,它将把输入解释为 UTF-8。
您的 md5 散列不是有效的 UTF-8,但 Buffer 构造函数试图从中构造一个有效的 UTF-8 字符串。在我看来,它应该用 replacement characters 代替无效字节,但它似乎最终做的是以下内容:对于每个以 0
作为第一位的字节,没有任何改变(它们已经有效),对于以 1
作为第一位的每个字节,它将字节编码为以下两个字节:
110000xx 10xxxxxx
其中 x
是它正在编码的字节的位。在您的情况下,这种情况发生了八次,总是导致 c2
或 c3
后跟另一个字节。所有在第一个位置有 0
的字节都被正常编码。你最终得到了八个额外的字节,并且 16 + 8 = 24
:
您应该指定您希望缓冲区接受二进制:
console.log(new Buffer(key1, 'binary'));
并且,由于 Buffer 构造函数已弃用,您应该切换到 Buffer.from:
console.log(Buffer.from(key1, 'binary'));
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
md5 不应该总是 return 16 字节摘要吗?
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'
不是 digest
的可识别编码类型。默认情况下使用 'buffer'
类型的编码。
而是使用 'hex'
或 'base64'
var key1 = crypto.createHash('md5').update('abcdefgh').digest('hex');
key1.length
// => 16
key1.toString()
// => 'e8dc4081b13434b45189a720b77b6818'
注意输出是 32 个字符,其中每 2 个字符代表一个十六进制格式的字节。
所以哈希大小实际上是 (32/2=16) 16 字节.
binary
output is self explanatory, no encoding
嗯,不,这不是不言自明的。这是一个未记录的参数值。但是,请注意 encoding
是一个 可选的 参数。
如果在调用 digest
时不使用参数,您仍然会得到 16 字节的结果
var key1 = crypto.createHash('md5').update('abcdefgh').digest()
key1.length
// => 16
key1.toString()
// => '��@��44�Q�� �{h\u0018'
key1.toString().length
// => 16
请注意,当使用 'buffer'
类型时,Buffer
的默认编码是 'utf8'
。所以当我们调用 buffer.toString
时,我们得到了这个讨厌的输出。你看到里面的 \u
了吗?那是统一码。如果您没有使用正确的 digest
参数,您可以轻松地将缓冲区转换为 hex
字符串(或 base64
),
// digest defaults to 'buffer' for unrecognized type
var key1 = crypto.createHash('md5').update('abcdefgh').digest('')
key1.length
// => 16
key1.toString()
// => '��@��44�Q�� �{h\u0018'
key1.toString('hex')
// => 'e8dc4081b13434b45189a720b77b6818'
无论传递给摘要的参数如何,缓冲区中的结果字节都是相同的。编码只是传递给缓冲区,只要您选择将缓冲区转换为字符串,就可以更改编码。
Buffer 构造函数(已弃用)需要第二个编码参数。如果您不指定,它将把输入解释为 UTF-8。
您的 md5 散列不是有效的 UTF-8,但 Buffer 构造函数试图从中构造一个有效的 UTF-8 字符串。在我看来,它应该用 replacement characters 代替无效字节,但它似乎最终做的是以下内容:对于每个以 0
作为第一位的字节,没有任何改变(它们已经有效),对于以 1
作为第一位的每个字节,它将字节编码为以下两个字节:
110000xx 10xxxxxx
其中 x
是它正在编码的字节的位。在您的情况下,这种情况发生了八次,总是导致 c2
或 c3
后跟另一个字节。所有在第一个位置有 0
的字节都被正常编码。你最终得到了八个额外的字节,并且 16 + 8 = 24
:
您应该指定您希望缓冲区接受二进制:
console.log(new Buffer(key1, 'binary'));
并且,由于 Buffer 构造函数已弃用,您应该切换到 Buffer.from:
console.log(Buffer.from(key1, 'binary'));