如何将unicode字符串中每个字符的二进制数据与下一个字符的二进制数据分开?

时间:2017-04-01 11:36:57

标签: javascript string encoding character-encoding binary

在JavaScript中

我可以使用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"

那么二进制读取过程如何知道一个字符使用了多少字节?有什么像分隔符吗?

2 个答案:

答案 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 表示:

  • 0xxxxxxx
  • 110xxxxx 10xxxxxx
  • 1110xxxx 10xxxxxx 10xxxxxx
  • 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

所以,使用前面的例子:

  • A(U + 0041)= 0x41
  • ñ(U + 00F1)= 0xC3 0xB1
  • (U + 096A)= 0xE0 0xA5 0xAA
  • (U + 1F4AA)= 0xF0 0x9F 0x92 0xAA

此编码具有可以从第一个字节的值确定序列中的字节数的属性。此外,前导字节可以很容易地与连续字节区分开来:

  • 0xxxxxxx =单字节字符(ASCII兼容)
  • 10xxxxxx = 2字节,3字节或4字节字符的连续字节
  • 110xxxxx = 2字节字符的前导字节
  • 1110xxxx = 3字节字符的前导字节
  • 11110xxx = 4字节字符的前导字节
  • 11111xxx =未使用

答案 1 :(得分:2)

在内部,JS使用UTF-16,也就是说,来自平面0的每个代码点都占用一个16位单位,而更高的平面字符则表示为代理对并使用两个单位。

源编码是UTF-8,也就是说,一个字符需要1到4个字节,具体取决于第一个字节的前导位。