写点什么

一文读懂字符与编码

这篇文章是从 0 到 1 自定义富文本渲染的原理篇之一,此外你还可能感兴趣:


欢迎关注同名公众号:非专业程序员 Ping

一、字符/Character

对用户可见的"一个字符",通常是我们在屏幕上看到的一个字母、数字、emoji 或组合字符。


比如:aé👨‍👩‍👧‍👦

二、字符编码标准/字符集

字符编码标准定义的是如何将字符映射到唯一编码,常见的字符编码标准比如ASCIIUnicodeGBK

2.1 ASCII

ASCII(7 位)定义了 128 个字符的唯一编码,包括数字 0 到 9、小写字母 a 到 z、大写字母 A 到 Z 以及常用标点符号等。

2.2 Unicode

Unicode 又叫万国码,目标是为所有字符定义唯一编码(Code Point)。为了解决 ASCII/GBK 不能定义全部字符的问题。


比如:


a -> U+0061


👨 -> U+1F468


注意


Unicode 只负责分配码位(Code Point),并不决定具体的存储形式。


Unicode 的前 128 个码点与 ASCII 相同。

2.2.1 Code Point

Code Point 也叫码位,Unicode 中为每个字符分配的唯一编码。


一个字符可以对应一个或多个 Code Point,比如:


  • aU+0061,对应 1 个 Code Point

  • 👨‍👩‍👧‍👦U+1F468 (👨) + U+200D (ZWJ) + U+1F469 (👩) + U+200D (ZWJ) + U+1F467 (👧) + U+200D (ZWJ) + U+1F466 (👦)对应 7 个 Code Point

  • éU+00E9U+0065 + U+0301


备注:

在 Unicode 中,é实际上有两种表示方式:

单一字符表示法 :即直接使用U+00E9这个单独的 Unicode 码位表示é

组合字符表示法 :使用U+0065(字母e)和U+0301(重音符号)两个 Unicode 码位来表示一个é字符。

为什么会有这两种表示法?

历史原因:Unicode 设计时考虑到了不同语言的需求,许多语言(如法语、西班牙语等)使用带有重音符号的字符,因此,Unicode 同时支持这两种表示方式。

兼容性:一些旧的系统或字体可能只支持分解字符表示法,因此,Unicode 也保留了这种组合字符的方式,以提高兼容性。

2.2.2 Code Unit

Code Unit 也叫码元(代码单元),表示计算机中实际存储 Unicode 的基本单位,取决于编码方式。


比如:


  • UTF-8Code Unit是 1 字节(8 Bit);比如:a在 UTF-8 编码下占 1 个字节,表示为0x61

  • UTF-16Code Unit是 2 字节(16 Bit);比如:a在 UTF-16 编码下占 2 个字节,表示为0x0061

  • UTF-32Code Unit是 4 字节(32 Bit);比如:a在 UTF-32 编码下占 4 个字节,表示为0x00000061

三、字符编码方式

字符编码方式决定了字符如何存储、传输和解码;常见的编码方式有:UTF-8、UTF-16、UTF-32 等


  • UTF-8:可变长度,用 1 到 4 个字节来存储 Unicode 字符;为了节省存储资源。

  • UTF-16:可变长度,用 2 或 4 个字节存储字符。

  • UTF-32:固定长度,每个字符始终使用 4 字节存储。


比如:


é的 Code Point 是:U+0065 + U+0301


当以UTF-32方式编码时,每个 Code Point 未超过 4 字节,所以表示为:0x00000065,0x00000301


当以UTF-16方式编码时,每个 Code Point 未超过 2 字节,所以表示为:0x0065,0x0301


当以UTF-8方式编码时,0x0301 值超过了 128,需要按UTF-8格式拆分为 0xCC,0x81,所以表示为:0x65,0xCC,0x81


Q:UTF-8编码为什么是按 128 做比较,按理说 1 字节(0xFF)表示的最大值是 255?

A:有两个原因:一是为了与ASCII兼容,ASCII只支持了 128 个字符编码,在UTF-8编码中,前 128 位与ASCII编码相同;二是UTF-8编码中,会将第一个字节的高位部分用来标识这个字符的编码长度,具体为:

  • 0xxxxxxx:表示 1 字节字符(ASCII 范围)

  • 110xxxxx:表示 2 字节字符

  • 1110xxxx:表示 3 字节字符

  • 11110xxx:表示 4 字节字符



欢迎关注同名公众号:非专业程序员 Ping

发布于: 刚刚阅读数: 6
用户头像

还未添加个人签名 2019-03-12 加入

还未添加个人简介

评论

发布
暂无评论
一文读懂字符与编码_swift_非专业程序员Ping_InfoQ写作社区