我正在尝试从í
(237)显示字符0xed
。
String.fromCharCode
会产生正确的结果:
String.fromCharCode(0xed); // 'í'
但是,使用Buffer
:
var buf = new Buffer(1);
buf.writeUInt8(0xed,0); // <Buffer ed>
buf.toString('utf8'); // '?', same as buf.toString()
buf.toString('binary'); // 'í'
对Buffer.toString
使用'二进制'是deprecated所以我想避免这种情况。
其次,我还可以预期传入数据是多字节的(即UTF-8),例如:
String.fromCharCode(0x0512); // Ԓ - correct
var buf = new Buffer(2);
buf.writeUInt16LE(0x0512,0); // <Buffer 12 05>, [0x0512 & 0xff, 0x0512 >> 8]
buf.toString('utf8'); // Ԓ - correct
buf.toString('binary'); // Ô
请注意,这两个示例都不一致。
那么,我错过了什么?我假设我不应该做什么? String.fromCharCode
是否神奇?
答案 0 :(得分:7)
似乎您可能假设String
和Buffer
使用相同的位长和编码。
JavaScript String
为16-bit, UTF-16 sequences,而节点Buffer
为8位序列。
UTF-8也是一种可变字节长度编码,代码点消耗between 1 and 6 bytes。例如,í
的UTF-8编码需要2个字节:
> new Buffer('í', 'utf8')
<Buffer c3 ad>
并且,0xed
本身不是UTF-8编码中的有效字节,因此?
表示“未知字符”。但是,它是与String.fromCharCode()
一起使用的有效UTF-16代码。
此外,您为第二个示例建议的输出似乎不正确。
var buf = new Buffer(2);
buf.writeUInt16LE(0x0512, 0);
console.log(buf.toString('utf8')); // "\u0012\u0005"
您可以绕过String.fromCharCode()
以查看UTF-8编码。
var buf = new Buffer(String.fromCharCode(0x0512), 'utf8');
console.log(buf); // <Buffer d4 92>