所以我尝试使用此函数在节点js中散列¤
字符
crypto.createHash('md5').update('¤', 'ascii').digest('hex')
给md5哈希
f37c6f3896b2c85fbbd01ae32e47b43f
并使用Buffer
crypto.createHash('md5').update(new Buffer('¤', 'ascii').toString()).digest('hex')
给出这样的结果:
9b759040321a408a5c7768b4511287a6
我尝试调试Hash.update()
以查看内部但我似乎无法编译。
为什么crypto
编码方法与Buffer
不同?是什么让它与众不同?
答案 0 :(得分:3)
crypto的编码方式与缓冲区的编码方式相同,所以让我们暂时忽略它。这是问题的简化:
const text = '¤';
const b1 = Buffer.from(text, 'ascii');
const b2 = Buffer.from(b1.toString());
b1和b2不是相同的字节。 b1是[0xa4],由于0xa4不是ASCII的一部分,所以没有多大意义; Node is using the same code to encode strings as ASCII and Latin-1 here。我不知道这是出于兼容性或性能原因还是什么,但似乎是一个坏主意,导致Buffer.from(s, 'ascii')
与Buffer.from(Buffer.from(s, 'ascii').toString('ascii'), 'ascii')
不同的值,并且似乎没有记录在任何地方
在现代版本的Node中,默认编码为UTF-8,因此b1.toString()
将尝试将0xa4
解释为UTF-8,失败并生成替换字符( ),编码如[0xef,0xbf,0xbd]。在Node的非现代版本中,它将执行依赖于环境的错误而不是一致的错误。
您可以通过传递缓冲区而不是缓冲区的UTF-8编码来使您的操作得到相同的结果:
crypto.createHash('md5').update(new Buffer('¤', 'ascii')).digest('hex')
(请注意.toString()
如何删除)
但正确的代码,能够散列任何Unicode代码点序列,将改为使用UTF-8。
crypto.createHash('md5').update('¤', 'utf8').digest('hex')
crypto.createHash('md5').update(Buffer.from('¤', 'utf8')).digest('hex')