【问题标题】:How can C# 16 bit chars encode all Unicode characters?C# 16 位字符如何编码所有 Unicode 字符?
【发布时间】:2018-09-30 03:02:43
【问题描述】:

我读到 C# 将 unicode 字符存储在 char(又名 System.Char)变量中,这些变量具有 16 位的固定长度。但是,16 位不足以存储所有 Unicode 字符!在这种情况下,C# 的 char 变量如何支持 Unicode?​​p>

【问题讨论】:

标签: c# unicode char


【解决方案1】:

简而言之:代理

这是个好问题。 Unicode 比大多数人想象的要复杂,因为它引入了多个新概念(字符集、代码点、编码、代码单元),但我会尽量给出一个几乎完整的答案。

简介:

Unicode 是一个字符集。字符集只是字符和代码点对的列表。代码点只是用于识别配对字符的数字。 UTF-8、UTF-16 和 UTF-32 是编码。编码定义数字(代码点)如何以二进制形式(作为代码单元)表示。代码单元可以由一个或多个字节组成。 (实际上原始的 ASCII 码单元甚至只有 7 位长,但这是另一回事 ?)

记住:字符集由代码点组成,编码由代码单元组成。

C# char 类型表示一个 UTF-16 字符(代码单元)。 UTF-16 是 Unicode 字符集的可变长度/多字节编码。含义字符可以由一个或两个 16 位代码单元表示。超过 16 位的 Unicode 代码点由两个 UTF-16 代码单元表示,它们等于四个字节。

现在回答您的问题:如何?

Unicode 最初的想法是1 character = 1 code point。但是 UCS-2 的原始编码(现在已过时)使用两个字节(16 位)并且只能编码 65,536 个代码点。不久之后,这对于不断增长的 Unicode 字符集来说还不够。哦,真的,他们怎么想的?两个字节显然是不够的。为了解决这个问题,Unicode 必须退后一步,引入代理项。

因此诞生了UTF-16,它是一种实现代理项的变长/多字节(16位代码单元)编码。此代理项是特殊的 16 位代码单元,等于在 Unicode 中定义的代码点,这些代码点明确不是字符。在解析文本时找到一个代理只是意味着,您还必须读取接下来的 16 位并将两个 16 位单元(代理和后续代码单元)解释为一个组合的 32 位 Unicode 代码点。

UTF-32 是一种固定的四字节编码,它足够大以避免空间问题,并且可以将 1 个字符映射到 1 个代码点,但 UTF-32 也必须处理代理,因为UTF 编码基于 Unicode 标准,代理项是 Unicode 字符集定义的一部分。

UTF-8 也是一种可变长度/多字节编码,但具有另一种有趣的编码技术。简而言之:代码单元中前导零的数量定义了最多四个后续字节的数量,这些字节必须组合成一个 Unicode 代码点。

【讨论】:

    猜你喜欢
    • 2022-10-14
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多