为什么“缓冲区”和“新的缓冲区(buffer.toString())”并不总是字节一致的?

我期待new Buffer(buffer.toString())将始终是字节对于字节相等。 但是,我遇到了一个不正确的情况。

首先,这是一个真实的情况:

 var buf1 = new Buffer(32); for (var i = 0 ; i < 32 ; i++) { buf1[i] = i; } console.log(buf1); console.log(new Buffer(buf1.toString())); <Buffer 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f> <Buffer 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f> 

但是,这是一个不正确的情况:

 var buf2 = crypto.createHmac('sha256', 'key') .update('string') .digest(); console.log(buf2); console.log(new Buffer(buf2.toString())); <Buffer 97 d1 5b ea ba 06 0d 07 38 ec 75 9e a3 18 65 17 8a b8 bb 78 1b 2d 21 07 64 4b a8 81 f3 99 d8 d6> <Buffer ef bf bd ef bf bd 5b ef bf bd ef bf bd 06 0d 07 38 ef bf bd 75 ef bf bd ef bf bd 18 65 17 ef bf bd ef bf bd ef bf bd 78 1b 2d 21 07 64 4b ef bf bd ef ... > 

buf2有什么不同,使new Buffer(buf2.toString())不等于buf2字节?

就JS而言, Buffer是一个对象,因此您正在比较对象引用。 由于两个缓冲区实际上不是相同的实例,所以这种相等检查( ===== )永远不会是真的。

为了比较缓冲区内容,如果节点v0.12或更新,可以使用类似buffer.equals(buffer2)东西。 对于较旧的节点版本,您将不得不使用循环来逐字节地检查。

附加说明:

调用.toString()将二进制数据转换为UTF-8。 如果该数据中有无效的UTF-8字符,则这些字符通常会被replace为\uFFFD字符。 当这个replace发生时,内容现在是不同的,导致equals()返回false 。 事实上,你可以在第二个Buffer( ef bf bd的实例)中看到这个。