Node.js 为什么'buffer'和'newbuffer(buffer.toString())'不总是字节对字节相等?

Node.js 为什么'buffer'和'newbuffer(buffer.toString())'不总是字节对字节相等?,node.js,Node.js,我希望新缓冲区(Buffer.toString())总是字节对字节相等。然而,我遇到了一个事实并非如此的情况 首先,这是真实的情况: var buf1 = new Buffer(32);

我希望
新缓冲区(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 buf1=新缓冲区(32);
对于(var i=0;i<32;i++){
buf1[i]=i;
} 
console.log(buf1);
log(新缓冲区(buf1.toString());
然而,在这种情况下,情况并非如此:

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 ... >
var buf2=crypto.createHmac('sha256','key'))
.update('字符串')
.digest();
控制台日志(buf2);
log(新的缓冲区(buf2.toString());

buf2
有什么不同之处,使得
新的缓冲区(buf2.toString())
不等同于
buf2
的字节?

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

为了比较缓冲区内容,如果您有节点v0.12或更新版本,可以使用类似于
Buffer.equals(buffer2)
的内容。对于较旧的节点版本,必须使用循环逐字节检查

补充说明:


调用
.toString()
将二进制数据转换为UTF-8。如果该数据中存在无效的UTF-8字符,则这些字符通常将替换为替换字符
\uFFFD
。发生此替换时,内容现在不同,导致
equals()
返回
false
。事实上,您可以在第二个缓冲区(ef bf bd的实例)中看到这一点。

@DaveNewton-huh?它编码到
utf8
,然后默认情况下
newbuffer(str)
解码
utf8
——我想。这里的
toString()
实现是
Buffer.prototype.toString()
@dimadima完全没有注意到;抱歉。在将缓冲区转换为字符串之前,是否要将其转换为更为字符串-y的格式(如十六进制或base64)?你到底想完成什么?缓冲区的字符串表示形式不会与缓冲区本身具有相同的字节,除非缓冲区已经包含合理的字符串。@DaveNewton:是的,当我试图使用时出现了问题,然后只是想将其返回到
缓冲区()
@DaveNewton为什么字符串表示不能对原始缓冲区进行1对1的编码/解码?我的意思是,编码的、打印的字符串可能包含没有您可以读取的标志符号的字节,但我认为这与往返编码无关。在上面的第二种情况下,
console.log(buf2.equals(新缓冲区(buf2.toString()))
打印
false
。你知道为什么吗?调用
.toString()
将二进制数据转换为UTF-8。如果该数据中存在无效的UTF-8字符,则这些字符通常将替换为替换字符
\uFFFD
。发生此替换时,内容现在不同,导致
equals()
返回
false
。事实上,您可以在第二个缓冲区中看到这一点(ef-bf-bd的实例)。是的,我忘了utf-8是怎么工作的。如果你想更新你的答案,我会投票/接受。