我在从特定的Uint8Array转换为字符串然后返回时遇到问题。我正在使用本机支持TextEncoder / TextDecoder模块的浏览器和Chrome。
如果我从一个简单的案例开始,一切似乎都很好:
const uintArray = new TextEncoder().encode('silly face demons');
// Uint8Array(17) [115, 105, 108, 108, 121, 32, 102, 97, 99, 101, 32, 100, 101, 109, 111, 110, 115]
new TextDecoder().decode(uintArray); // silly face demons
但是以下情况并未给我期望的结果。在不涉及太多细节(与加密有关)的情况下,让我们从提供以下Uint8Array的事实开始:
Uint8Array(24) [58, 226, 7, 102, 202, 238, 58, 234, 217, 17, 189, 208, 46, 34, 254, 4, 76, 249, 169, 101, 112, 102, 140, 208]
我想要做的是将其转换为字符串,然后将字符串解密回原始数组,但是我明白了:
const uintArray = new Uint8Array([58, 226, 7, 102, 202, 238, 58, 234, 217, 17, 189, 208, 46, 34, 254, 4, 76, 249, 169, 101, 112, 102, 140, 208]);
new TextDecoder().decode(uint8Array); // :�f��:����."�L��epf��
new TextEncoder().encode(':�f��:����."�L��epf��');
...导致:
Uint8Array(48) [58, 239, 191, 189, 7, 102, 239, 191, 189, 239, 191, 189, 58, 239, 191, 189, 239, 191, 189, 17, 239, 191, 189, 239, 191, 189, 46, 34, 239, 191, 189, 4, 76, 239, 191, 189, 239, 191, 189, 101, 112, 102, 239, 191, 189, 239, 191, 189]
该数组已加倍。编码有点不合时宜。谁能告诉我为什么数组增加了一倍(我假设它是原始数组的替代表示...?)。而且,更重要的是,有没有办法我可以回到原始数组(即,将得到的数组加倍)?
答案 0 :(得分:1)
您试图将数组中的代码点转换为utf-8
时没有意义或不允许使用。 >= 128
几乎所有内容都需要特殊处理。其中一些是允许的,但是多个字节序列的前导字节,而某些254
则是不允许的。如果要来回转换,则需要确保创建有效的utf-8
。此处的代码页布局可能有用:https://en.wikipedia.org/wiki/UTF-8#Codepage_layout,非法字节序列的描述也可能有用:https://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences。
作为一个具体的例子,
let arr = new TextDecoder().decode(new Uint8Array([194, 169]))
let res = new TextEncoder().encode(arr) // => [194, 168]
之所以有效,是因为[194, 169]
对于©是有效的utf-8,但:
let arr = new TextDecoder().decode(new Uint8Array([194, 27]))
let res = new TextEncoder().encode(arr) // => [239, 191, 189, 27]
不是因为这不是有效序列。