Skip to main content

字符编码

字符编码是将数字分配给图形字符的过程,特别是人类语言的书面字符,允许使用数字计算机存储传输转换它们。[1]构成字符编码的数字值称为“代码点”,统称为“代码空间”、“代码页面”或“字符映射”。

ASCII中编码的带有“维基百科”一词的打孔磁带。孔的存在和不存在分别代表1和0;例如,“W”编码为“1010111”。

与光学或电报相关的早期字符代码只能代表书面语言中使用的字符子集,有时仅限于大写字母数字和一些标点符号。现代计算机系统中数据数字表示成本低,允许更复杂的字符代码(如Unicode),这些代码代表了许多书面语言中使用的大多数字符。使用国际公认标准的字符编码允许在全球范围内以电子形式交换文本。

与字符编码相关的术语
KB Dubeolsik for Old Hangul (NG3).svg
  • 字符是具有语义值的最小文本单位。
  • 字符集是多种语言可能使用的字符集合。示例:拉丁字符集被英语和大多数欧洲语言使用,尽管希腊字符集仅由希腊语使用。
  • 编码字符集是每个字符对应一个唯一数字的字符集。
  • 编码字符集的代码点是字符集或代码空间中允许的任何值。
  • 代码空间是一系列整数,其值为代码点
  • 代码单元是一个位序列,用于在给定编码表单中对剧目的每个字符进行编码。在某些文档中,这被称为代码值。
角色库(抽象字符集)

角色曲目是一套抽象的,包含100多万个字符,包括拉丁文、西里尔文、中文、韩文、日文、希伯来语和阿拉姆文等多种文字。

角色曲目中还包括音乐符号等其他符号。Unicode和GB18030标准都有字符库。当新字符添加到一个标准中时,另一个标准也会添加这些字符,以保持奇偶校验。

代码单元大小相当于特定编码的位测量:

  • US-ASCII中的代码单元由7位组成;
  • UTF-8EBCDIC和GB18030中的代码单元由8位组成;
  • UTF-16中的代码单元由16位组成;
  • UTF-32中的代码单元由32位组成。

代码单元的示例:考虑一字母“abc”,后跟U+10400?DESERET大写字母LONG I(用1个char32_t、2个char16_t或4个char8_t表示)。该字符串包含:

  • 四个字符;
  • 四个代码点
  • 要么:
    UTF-32中的四个代码单元(00000061,00000062,00000063,00010400)
    UTF-16(0061、0062、0063、d801、dc00)中的五个代码单元,或
    UTF-8中的七个代码单元(61、62、63、f0、90、90、80)。

在Unicode中引用字符的约定是以“U+”开头,然后以十六进制表示代码点值。Unicode标准的有效代码点范围为U+0000到U+10FFFF,包括,分为17个平面,由数字0到16标识。U+0000到U+FFFF范围内的字符在平面0中,称为基本多语言平面(BMP)。这个平面包含最常用的字符。其他平面上U+10000到U+10FFFF范围内的字符称为补充字符

下表显示了代码点值的示例:

性格 Unicode代码点 字形
拉丁语A U+0041 Α
拉丁语锋利的S U+00DF ß
汉朝东方 U+6771 东方
安珀桑德 U+0026 &
倒感叹号 U+00A1 ¡
部分标志 U+00A7 §

代码点由一系列代码单元表示。映射由编码定义。因此,表示代码点所需的代码单元数量取决于编码:

  • UTF-8:代码点映射到一个、两个、三个或四个代码单元的序列。
  • UTF-16:代码单元的长度是8位代码单元的两倍。因此,任何标量值小于U+10000的代码点都使用单个代码单元进行编码。值为U+10000或以上的代码点每个需要两个代码单元。这些代码单元对在UTF-16中有一个唯一的术语:“Unicode代理对”。
  • UTF-32:32位代码单元足够大,每个代码点都表示为单个代码单元。
  • GB18030:由于代码单元较小,每个代码点的多个代码单元很常见。代码点映射到一个、两个或四个代码单元。

Unicode编码模型

Unicode及其并行标准ISO/IEC 10646通用字符集共同构成了一个现代、统一的字符编码。他们没有将字符直接映射到八位数(字节),而是分别定义了可用的字符、相应的自然数字(代码点)、这些数字如何编码为一系列固定大小的自然数字(代码单元),以及最后这些单元如何编码为八位数流。这种分解的目的是建立一套通用字符,该字符可以通过多种方式编码。[8] 要正确描述此模型,需要比“字符集”和“字符编码”更精确的术语。现代模型中使用的术语如下:[8]

字符库是系统支持的全套抽象字符。剧目可能会关闭,即如果不创建新标准(如ASCII和大多数ISO-8859系列),则不允许添加,也可能是开放的,允许添加(如Unicode和有限的Windows代码页面)。给定剧目中的字符反映了就如何将写作系统划分为基本信息单元所做的决定。拉丁字母希腊字母西里尔字母的基本变体可以分为字母、数字、标点符号和空格等几个特殊字符,这些字符都可以按简单的线性顺序排列,按读取顺序显示。但即使使用这些字母表,变音符也造成了复杂因素:它们可以被视为包含字母和变音符(称为预合成字符)的单个字符的一部分,也可以被视为单独的字符。前者允许更简单的文本处理系统,但后者允许在文本中使用任何字母/变音符组合。连字也带来了类似的问题。其他书写系统,如阿拉伯语和希伯来语,都以更复杂的字符库表示,因为需要容纳双向文本和字形等内容,这些文本和字形在不同情况下以不同方式连接在一起。

编码字符集(CCS)是一个将字符映射到代码点函数(每个代码点代表一个字符)。例如,在给定的曲目中,拉丁字母中的大写字母“A”可以用代码点65、字符“B”到66等表示。多个编码字符集可能共享相同的曲目;例如ISO/IEC 8859-1和IBM代码页面037和500都涵盖了相同的曲目,但将它们映射到不同的代码点。

字符编码形式(CEF)是将代码点映射到代码单元,以方便在将数字表示为固定长度位序列的系统中(即几乎任何计算机系统)中的存储。例如,一个以16位单位存储数字信息的系统只能直接表示每个单元中的代码点0到65,535,但较大的代码点(例如65,536到140万)可以通过使用多个16位单元来表示。此通信由CEF定义。

接下来,字符编码方案(CES)是将代码单元映射到八位数序列,以方便在基于八位数的文件系统上存储或通过基于八位数的网络传输。简单的字符编码方案包括UTF-8UTF-16BEUTF-32BEUTF-16LEUTF-32LE;复合字符编码方案,如UTF-16UTF-32ISO/IEC 2022,通过使用字节顺序标记转义序列在几个简单的方案之间切换;压缩方案试图将每个代码单元(如SCSUBOCUPunycode)使用的字节数最小化。

虽然UTF-32BE是一个更简单的CES,但大多数使用Unicode的系统要么使用UTF-8,它向后兼容固定宽度的ASCII,并将Unicode代码点映射到八位数的变宽度序列,要么使用UTF-16BE,后者向后兼容固定宽度的UCS-2BE,并将Unicode代码点映射到16位单词的可变宽度序列。有关详细讨论请参阅Unicode编码比较

最后,可能有一个更高级别协议,为选择Unicode字符的特定变体提供更多信息,特别是在Unicode中有一些区域变体与同一字符“统一”的情况下。一个例子是XML属性xml:lang。

Unicode模型使用术语字符映射来描述历史系统,这些系统直接将字符序列分配给字节序列,涵盖所有CCS、CEF和CES层。

字符集、字符映射和代码页面

从历史上看,“字符编码”、“字符映射”、“字符集”和“代码页面”等术语在计算机科学中是同义词,因为同一标准将指定字符库以及如何将字符编码成代码单元流——通常每个代码单元只有一个字符。但现在这些术语具有相关但不同的含义,[9] 由于标准机构在编写和统一许多不同的编码系统时努力使用准确的术语。[8]无论如何,这些术语仍然可以互换使用,字符集几乎无处不在。

代码页面”通常是指面向字节的编码,但对于某些编码集(涵盖不同的脚本),其中许多字符在大多数或所有代码页面中共享相同的代码。著名的代码页面套件是“Windows”(基于Windows-1252)和“IBM”/“DOS”(基于代码页面437),有关详细信息,请参阅Windows代码页面。大多数(但不是所有)被称为代码页面的编码都是单字节编码(但请参阅字节大小的八位数)。

IBM的字符数据表示架构(CDRA)指定具有编码字符集标识符(CCSID)的实体,每个标识符都不同地称为“字符集”、“字符集”、“代码页面”或“CHARMAP”。[8]

“代码页面”一词不出现在首选“charmap”的Unix或Linux中,通常在更大的区域设置上下文中。

与“编码字符集”不同,“字符编码”是从抽象字符到编码单词的映射。HTTP(和MIME)语中的“字符集”与字符编码相同(但与CCS不同)。

传统编码”是一个术语,有时用于描述旧字符编码,但含义模糊。它的大部分使用是在Unicodification的背景下,它指的是未能涵盖所有Unicode代码点的编码,或者更笼统地说,使用有点不同的字符库:代表一个Unicode字符的几个代码点,[10]或反之亦然(例如,见代码第437页)。一些来源仅将编码称为遗留,因为它先于Unicode。[11]所有Windows代码页面通常都被称为遗留页面,因为它们比Unicode更年,也因为它们无法代表所有221可能的Unicode代码点。

字符编码翻译

由于使用了多种字符编码方法(以及需要向后兼容存档数据),开发了许多计算机程序,在编码方案之间将数据转换为数据传输形式。下文引用其中一些。

跨平台

  • 网络浏览器——大多数现代网络浏览器都具有自动字符编码检测功能。例如,在Firefox 3上,请参阅视图/字符编码子菜单。
  • iconv – 转换编码的程序和标准化API
  • luit – 将输入和输出编码转换为交互式运行的程序的程序
  • convert_encoding.py – 基于Python的实用程序,用于在任意编码和行尾之间转换文本文件。[12]
  • decodeh.py – 启发式猜测字符串编码的算法和模块。[13]
  • Unicode的国际组件-一组用于执行字符集转换的C和Java库。uconv可以从ICU4C使用。
  • chardet – 这是Mozilla自动编码检测代码翻译成Python计算机语言。
  • 较新版本的Unix文件命令试图对字符编码进行基本检测(也可以在Cygwin上使用)。
  • charset C++模板库,具有简单的界面,可在C++/用户定义的流之间转换。charset定义了许多字符集,并允许您使用Unicode格式来支持外部性

类似Unix

  • cmv – 转码文件名的简单工具。[14]
  • convmv – 将文件名从一个编码转换为另一个编码。[15]
  • cstocs – 将捷克语和斯洛伐克语的文件内容从一个编码转换为另一个编码。
  • enca – 分析给定文本文件的编码。[16]
  • 重新编码 – 将文件内容从一个编码转换为另一个编码[17]
  • utrac – 将文件内容从一个编码转换为另一个编码。[18]

Windows

  • Encoding.Convert – .NET API[19]
  • MultiByteToWideChar/WideCharToMultiByte – 从ANSI转换为Unicode,从Unicode转换为ANSI[20]
  • cscvt – 字符集转换工具[21]
  • enca – 分析给定文本文件的编码。[22]