UTF-8 - Linux手册页
Linux程序员手册 第7部分
更新日期: 2019-03-06
名称
UTF-8-ASCII兼容的多字节Unicode编码
说明
Unicode 3.0字符集占用16位代码空间。最明显的Unicode编码(称为UCS-2)由一系列16位字组成。作为许多16位字符的一部分,此类字符串可以包含-aq \ 0aq或aq / aq之类的字节,这些字节在文件名和其他C库函数参数中具有特殊含义。此外,大多数UNIX工具都希望使用ASCII文件,并且未经重大修改就无法将16位字作为字符读取。由于这些原因,UCS-2不适合在文件名,文本文件,环境变量等中使用Unicode进行外部编码。 ISO 10646通用字符集(UCS)是Unicode的超集,占据了甚至更大的代码空间-31位-并且其明显的UCS-4编码(32位单词序列)具有相同的问题。
Unicode和UCS的UTF-8编码不存在这些问题,并且是在UNIX风格的操作系统上使用Unicode的常见方式。
Properties
UTF-8编码具有以下不错的属性:
- *
UCS字符0x00000000至0x0000007f(经典的US-ASCII字符)被简单地编码为字节0x00至0x7f(与ASCII兼容)。这意味着仅包含7位ASCII字符的文件和字符串在ASCII和UTF-8下都具有相同的编码。
- *
所有大于0x7f的UCS字符都被编码为仅由0x80到0xfd范围内的字节组成的多字节序列,因此ASCII字节不能作为另一个字符的一部分出现,例如aq \ 0aq或aq /也没有问题。水
- *
UCS-4字符串的字典顺序保留。
- *
可以使用UTF-8对所有可能的2 ^ 31个UCS代码进行编码。
- *
UTF-8编码从不使用字节0xc0、0xc1、0xfe和0xff。
- *
代表单个非ASCII UCS字符的多字节序列的第一个字节始终在0xc2到0xfd的范围内,并指示该多字节序列的长度。多字节序列中的所有其他字节都在0x80到0xbf的范围内。这样可以轻松进行重新同步,并使编码成为无状态的,并且可以针对丢失的字节进行鲁棒处理。
- *
UTF-8编码的UCS字符最长可以为6个字节,但是Unicode标准没有指定0x10ffff以上的字符,因此Unicode字符在UTF-8中最多只能为4个字节。
Encoding
以下字节序列用于表示一个字符。使用的序列取决于字符的UCS代码编号:
- 0x00000000 - 0x0000007F:
0 xxxxxxx
- 0x00000080 - 0x000007FF:
110 xxxxx 10 xxxxxx
- 0x00000800 - 0x0000FFFF:
1110 xxxx 10 xxxxxx 10 xxxxxx
- 0x00010000 - 0x001FFFFF:
11110 xxx 10 xxxxxx 10 xxxxxx 10 xxxxxx
- 0x00200000 - 0x03FFFFFF:
111110 xx 10 xxxxxx 10 xxxxxx 10 xxxxxx 10 xxxxxx
- 0x04000000 - 0x7FFFFFFF:
1111110 x 10 xxxxxx 10 xxxxxx 10 xxxxxx 10 xxxxxx 10 xxxxxx
xxx位位置以二进制表示形式填充了字符代码编号的位,最高有效位在前(大端)。只能使用可以表示字符代码号的尽可能短的多字节序列。
UCS代码值0xd800-0xdfff(UTF-16替代)以及0xfffe和0xffff(UCS非字符)不应出现在符合标准的UTF-8流中。根据RFC 3629,不得使用U + 10FFFF以上的点,这会将字符限制为四个字节。
Example
Unicode字符0xa9 = 1010 1001(版权符号)以UTF-8编码为
11000010 10101001 = 0xc2 0xa9
且字符0x2260 = 0010 0010 0110 0000("不等于"符号)编码为:
11100010 10001001 10100000 = 0xe2 0x89 0xa0
Application notes
用户必须选择UTF-8语言环境,例如
出口LANG = en_GB.UTF-8
为了激活应用程序中的UTF-8支持。
必须了解所使用字符编码的应用程序软件应始终使用以下方式设置语言环境:
setlocale(LC_CTYPE,"")
然后程序员可以测试表达式
strcmp(nl_langinfo(CODESET)," UTF-8")== 0
确定是否已选择UTF-8语言环境,并因此确定所有纯文本标准输入和输出,终端通信,纯文本文件内容,文件名和环境变量是否都以UTF-8编码。
习惯于单字节编码(例如US-ASCII或ISO 8859)的程序员必须意识到,到目前为止所做的两个假设在UTF-8语言环境中不再有效。首先,单个字节不必再与单个字符相对应。其次,由于UTF-8模式下的现代终端仿真器还支持中文,日文和韩文的全角字符以及无间距的组合字符,因此输出单个字符并不一定像ASCII中那样将光标前进一个位置。今天应使用诸如mbsrtowcs(3)和wcswidth(3)之类的库函数来计算字符和光标位置。
从ISO 2022编码方案(例如VT100终端使用)切换到UTF-8的正式ESC序列为ESC%G(" \ x1b%G")。从UTF-8到ISO 2022的对应返回顺序为ESC%@(" \ x1b%@")。其他ISO 2022序列(例如用于切换G0和G1集的序列)不适用于UTF-8模式。
Security
Unicode和UCS标准要求UTF-8的生产者应使用尽可能短的形式,例如,产生具有首字节0xc0的两字节序列不合格。 Unicode 3.1增加了一个要求,即兼容程序不得在其输入中接受非最短格式。这是出于安全原因:如果检查用户输入是否存在可能的安全冲突,则程序可能仅检查ASCII版本的" /../"或";"。或NUL,而忽略了许多非ASCII方式以非最短UTF-8编码表示这些内容。
Standards
ISO / IEC 10646-1:2000,Unicode 3.1,RFC 3629,计划9。
另外参见
locale(1),nl_langinfo(3),setlocale(3),charsets(7),unicode(7)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。