我可以使用charCodeAt方法从单个字符中获取Unicode。
当我使用它将字符串转换为unicode数字时,我会得到以下结果:
"A".charCodeAt(0) === 65
"४".charCodeAt(0) === 2410
将这些十进制数转换为二进制数如下:
"A".charCodeAt(0).toString(2) === "1000001" // 1 byte, with padleft: "01000001"
"४".charCodeAt(0).toString(2) === "100101101010" // 2 bytes, with padleft: "0000100101101010"
这意味着,4符号使用2个字节来表示。但阅读过程如何知道呢?
它也可以是两个不同的字符" "
和"j"
:
String.fromCharCode(parseInt("00001001", 2)) === " " // horizontal tabulator
String.fromCharCode(parseInt("01101010", 2)) === "j"
。
那么二进制读取过程如何知道一个字符使用了多少字节?有什么像分隔符吗?
答案 0 :(得分:4)
Unicode将每个字符*映射到整数“代码点”。有效代码点是U + 0000到U + 10FFFF,允许超过一百万个字符(尽管大多数字符尚未分配)。
(*它有点复杂,因为有“组合字符”,其中一个用户感知字符可以由多个代码点表示。并且一些字符具有预先组合和分解的表示。例如,西班牙字母ñ
可以表示为单个代码点U + 00F1,也可以表示为序列U + 006E U + 0303(n
+组合波浪号)。)
有三种不同的编码形式(不包括像UTF-9 and UTF-18这样的非常类型),可用于表示字符串中的Unicode字符。
UTF-32是最直接的:每个代码点由32位整数表示。所以,例如:
A
(U + 0041)= 0x00000041 ñ
(U + 00F1)= 0x000000F1 ४
(U + 096A)= 0x0000096A
(U + 1F4AA)= 0x0001F4AA 虽然简单,UTF-32使用大量内存(每个字符4个字节),很少使用。
UTF-16使用16位代码单元。字符U + 0000到U + FFFF(“基本多语言平面”)直接表示为单个代码单元,而字符U + 10000到U + 10FFFF表示为“代理对”。具体来说,从代码点减去0x10000(产生一个20位数),并使用这些位填写二进制序列110110xxxxxxxxxx 110111xxxxxxxxxx。例如,
A
(U + 0041)= 0x0041 ñ
(U + 00F1)= 0x00F1 ४
(U + 096A)= 0x096A
(U + 1F4AA)= 0xD83D 0xDCAA 为了使这个系统工作,代码点U + D800到U + DFFF永久保留给这个UTF-16代理机制,永远不会被分配给“真实”字符。
这是一种向后兼容性“黑客”,允许在1990年代的平台上表示完整的17-“平面”Unicode代码空间,这些平台的设计期望Unicode字符始终为16位。这包括Windows NT,Java和JavaScript。
UTF-8表示具有1-4个字节序列的Unicode代码点。具体来说,每个字符都用 shortest 表示:
所以,使用前面的例子:
A
(U + 0041)= 0x41 ñ
(U + 00F1)= 0xC3 0xB1 ४
(U + 096A)= 0xE0 0xA5 0xAA
(U + 1F4AA)= 0xF0 0x9F 0x92 0xAA 此编码具有可以从第一个字节的值确定序列中的字节数的属性。此外,前导字节可以很容易地与连续字节区分开来:
答案 1 :(得分:2)
在内部,JS使用UTF-16,也就是说,来自平面0的每个代码点都占用一个16位单位,而更高的平面字符则表示为代理对并使用两个单位。
源编码是UTF-8,也就是说,一个字符需要1到4个字节,具体取决于第一个字节的前导位。