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应该总是返回16字节的摘要吗?
答案 0 :(得分:2)
<强> hash.digest(encoding) docs 强>
计算要散列的所有数据的摘要(使用hash.update()方法)。编码可以是
'hex'
,'latin1'
或'base64'
。如果提供编码,则返回一个字符串;否则返回缓冲区。
'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
输出是自解释的,没有编码
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
了吗?那是unicode。如果您没有使用正确的hex
参数,则可以轻松地将缓冲区转换为base64
字符串(或digest
)
// 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'
无论传递给摘要的参数如何,缓冲区中的结果字节都是相同的。编码只是传递给缓冲区,只要您选择将缓冲区转换为字符串,就可以对其进行更改。
答案 1 :(得分:2)
Buffer构造函数(已弃用)需要第二个参数用于编码。如果您没有指定,则将输入解释为UTF-8。
您的md5哈希值无效UTF-8,但Buffer构造函数尝试从中构造有效的UTF-8字符串。在我看来,它应该用replacement characters替换无效字节,但它最终做的事情如下:对于每个字节都有0
作为第一位,没有任何改变(它们已经有效),对于每个字节都有1
作为第一位,它将字节编码为以下两个字节:
110000xx 10xxxxxx
x
s是其编码的字节的位。在您的情况下,这种情况会发生八次,这会导致c2
或c3
后跟另一个字节。在第一个位置具有0
的所有字节都被正常编码。最终会有8个额外字节,16 + 8 = 24
:
您应该指定您希望缓冲区接受二进制文件:
console.log(new Buffer(key1, 'binary'));
并且,由于不建议使用Buffer构造函数,因此应切换到Buffer.from:
console.log(Buffer.from(key1, 'binary'));