字符编码

ASCII编码的“ Wikipedia”一词打孔胶带。孔的存在和不存在分别代表1和0。例如,“ W”编码为“ 1010111”。

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

与光学或电报相关的早期角色代码只能代表以书面语言使用的字符的一个子集,有时仅限于上案例字母数字和一些标点符号。现代计算机系统中数据的数字表示的低成本允许更精细的字符代码(例如Unicode ),这些代表代表许多书面语言中使用的大多数字符。使用国际接受标准编码的字符允许以电子形式进行全球文本互换。

历史

字符代码的历史说明了使用曾经新的电气手段在远距离内对机器介导的基于机器介导的符号信息的不断发展的需求。最早的代码基于手动编码和密码系统,例如培根的密码盲文国际海上信号旗,以及汉字编码的中文电报代码的四位数编码( Hans Schjellerup ,1869年)。通过采用电气和电力技术技术,这些最早的代码适应了早期机器的新功能和局限性。 1840年代引入的最早著名的电传输字符代码Morse代码使用了四个“符号”的系统(短信号,长信号,短空间,长空间,长空间)来生成可变长度的代码。尽管Morse代码的商业用途是通过机械使用的,但它通常被用作手动代码,并通过电报钥匙手工生成并可以用耳朵解密,并持续使用业余无线电航空用途。大多数代码是固定长度代码(例如Unicode )的固定人均长度或可变长度序列。

字符编码系统的常见示例包括Morse代码, Baudot代码美国信息交换的标准代码(ASCII)和Unicode。 Unicode是一个定义明确且可扩展的编码系统,已取代了最早的字符编码,但是对当前的代码开发路径是众所周知的。

Baudot Code是一项五位编码,由1870年的埃米尔·鲍多特(OémileBaudot)于1874年创建,并于1874年获得专利,由唐纳德·默里(Donald Murray)于1901年修改,并由CCITT标准化为国际电报字母2号 ITA2)。错误地应用于ITA2及其许多变体。 ITA2遭受了许多缺点,并且经常被许多设备制造商改善,有时会引起兼容性问题。 1959年,美国军方定义了其Fieldata守则,这是由美国陆军信号军提出的六或七位法规。尽管Fieldata谈到了许多当时现代的问题(例如,安排了机器整理的字母和数字代码),但它没有达到其目标,并且是短暂的。 1963年,ASCII委员会(X3.4-1963)(X3.4-1963)(其中包含Fieldata委员会的至少一个成员WF Leubbert)发布了第一个ASCII守则,该委员会使用更简单的代码来解决了Fieldata的大多数缺点。许多变化都是微妙的,例如在某些数字范围内的可汇合字符集。 ASCII63是成功的,行业广泛采用,随着1967年ASCII代码的后续问题(添加了低写字母并修复了一些“控制代码”问题)ASCII67被广泛采用。 ASCII67的以美国为中心的性质在欧洲ECMA-6标准中有所解决。

带有EBCDIC角色集的Hollerith 80列打孔卡

赫尔曼·霍勒里斯(Herman Hollerith)在19世纪后期发明了打孔卡数据编码,以分析人口普查数据。最初,每个孔位置代表一个不同的数据元素,但是后来,数字信息是通过编号为0到9的编码数字信息,而列中的punch表示其行号。后来的字母数据是通过允许每列允许多个打孔来编码的。机电制表机在内部用脉冲的时机相对于通过机器的卡片运动而表示日期。当IBMIBM 603电子乘数开始进行电子处理时,它使用了各种与打孔卡代码相关的二进制编码方案。

IBM的二进制编码十进制BCD )是IBM最早在1953年在其702704计算机中使用的六位编码方案,以及其后来的7000系列1400系列,以及相关的外围设备。由于使用的打孔卡代码仅允许数字,大写英语字母和一些特殊字符,因此六个位就足够了。 BCD扩展了现有的简单四位数字编码,以包括字母和特殊字符,将其映射到已经广泛使用中的打孔卡编码。 IBMS代码主要用于IBM设备;该时代的其他计算机供应商具有自己的角色代码,通常是六位数,但通常具有阅读IBM设备上生产的磁带的能力。 BCD是IBM扩展的二进制编码十进制互换代码(通常缩写为EBCDIC)的先驱,这是一种1963年为IBM System/360开发的八位编码方案,其中包含更大的字符集,包括较低的案例字母。

在试图开发普遍可互换的角色编码时,1980年代的研究人员面临着一个困境,一方面,似乎有必要添加更多的位以适应其他角色,但另一方面,对于相对较小的角色集的用户来说在拉丁字母(仍然构成大多数计算机用户)的拉丁字母中,这些额外的位是当时的降低和昂贵的计算资源的巨大浪费(因为这些用户总是会归零)。在1985年,普通的个人计算机用户的硬盘驱动器只能存储约10兆字节,并且在批发市场上的价格约为250美元(如果在零售店单独购买的话,则更高),因此,当时制作每一个都非常重要位计数。

最终发现并发展为Unicode的折衷解决方案是打破假设(可以追溯到电报代码),即每个字符应始终直接与特定的位序列直接对应。取而代之的是,字符首先以称为代码点的抽像数字的形式映射到通用中间表示形式。然后,代码点将以各种方式表示,并且每个字符(代码单元)的默认位数都取决于上下文。要编码高于代码单元的长度(例如八位单位的256)的代码点,该解决方案是实现可变长度编码,其中逃生序列会表示应将后续位解析为更高的代码点。

术语

非正式地,通常可以互换使用术语“字符编码”,“字符映射”,“字符集”和“代码页”。从历史上看,相同的标准将指定字符曲目以及如何将它们编码到代码单元流中 - 通常每个代码单元单个字符。但是,由于出现了更复杂的字符编码,这些术语之间的区别变得很重要。

  • 字符是具有语义价值的最小文本单元。
  • 字符集是用于表示文本的元素集合。例如,拉丁字母希腊字母都是字符集。
  • 编码字符集是映射到唯一数字集的字符集。由于历史原因,这通常也称为代码页
  • 字符曲目是可以由特定编码字符集表示的字符集。曲目可能会关闭,这意味着没有创建新标准的情况不允许添加(与ASCII和ISO-8859系列的大多数一样);或者可以打开,允许添加(与Unicode一样,在有限的范围内Windows代码页面上也是如此)。
  • 代码点是字符集中字符的值或位置。
  • 代码空间是由编码字符集跨越的数值范围。
  • 代码单元是可以代表字符编码字符的最小位组合(用计算机科学术语,它是字符编码的单词大小)。例如,通用代码单元包括7位,8位,16位和32位。在某些编码中,有些字符是使用多个代码单元编码的;这种编码称为可变宽度编码

代码页

“代码页”是编码字符集的历史名称。

最初,一个代码页面引用了IBM标准字符集手册中的特定页码,该页码将定义特定的字符编码。包括MicrosoftSAPOracle Corporation在内的其他供应商也发布了自己的代码页面;最著名的代码页套件是“ Windows ”(基于Windows-1252)和“ IBM”/“ DOS”(基于代码第437页)。

尽管不再参考标准中的特定页码,但许多字符编码仍由其代码页码提及。同样,术语“代码页”通常仍用于参考字符编码。

术语“代码页”在UNIX或Linux中不使用,其中“ CharMap”是首选的,通常在较大的语言环境中。 IBM的字符数据表示架构(CDRA)指定具有编码字符集标识符( CCSID )的实体,每个实体都被称为“ charset”,“ conture set”,“代码页”,或“ charmap”。

代码单元

代码单位大小等效于特定编码的位测量:

代码点

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

  • UTF-8:代码点映射到一个,两个,三个或四个代码单元的序列。
  • UTF-16:代码单元的长度是8位代码单元的两倍。因此,标量值小于u+10000的任何代码点均使用单个代码单元编码。具有值u+10000或更高的代码点需要两个代码单元。这些代码单元在UTF-16中具有独特的术语: “ Unicode替代对”。
  • UTF-32:32位代码单元足够大,每个代码点都表示为单个代码单元。
  • GB 18030:由于小型代码单元,每个代码点多个代码单元很常见。代码点映射到一个,两个或四个代码单元。

人物

构成字符在字符编码之间变化的恰恰是什么。

例如,对于带有变节的字母,可以采用两种不同的方法来编码它们:它们可以用作单个统一字符(称为预先构成的字符),也可以用作组合成单个字形的单独字符。前者简化了文本处理系统,但是后者允许在文本中使用任何字母/变性组合。绑带构成类似的问题。

确切处理方式是在构造特定字符编码时必须做出的选择。一些写作系统,例如阿拉伯语和希伯来语,需要适应以不同方式加入的素描之类的东西,但代表相同的语义特征。

Unicode编码模型

Unicode及其并行标准,ISO/IEC 10646通用字符集,构成了字符编码的统一标准。 Unicode不是直接将字符映射到字节上,而是分别定义了一个编码的字符集,该字符集将字符映射到唯一的自然数字(代码点),如何将这些代码点映射到一系列固定尺寸的自然数(代码单位),最后如何映射这些单元被编码为八位字节(字节)。这种分解的目的是建立可以通过多种方式编码的通用字符集。为了准确描述这个模型,Unicode使用自己的术语集来描述其过程:

抽象字符曲目(ACR)是系统支持的整个抽象字符。 Unicode有一个开放的曲目,这意味着随着时间的推移,新角色将被添加到曲目中。

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

字符编码表格(CEF)是代码点到代码单元的映射,以促进将数字表示为固定长度的位序列(即实际上是任何计算机系统)的系统。例如,将数字信息存储在16位单元中的系统只能直接表示每个单元中代码0到65,535,但是使用多个16位单元可以表示较大的代码点(例如65,536至140万)。该对应关系由CEF定义。

字符编码方案(CES)是将代码单元映射到一系列八位位组中,以促进基于八位钟的文件系统或基于八位钟网络的传输的存储。简单的字符编码方案包括UTF-8UTF-16BEUTF-32BEUTF-16LEUTF-32LE ;复合字符编码方案,例如UTF-16UTF-32ISO/IEC 2022 ,通过使用字节订单标记逃生序列在几个简单方案之间进行切换;压缩方案试图最大程度地减少每个代码单元使用的字节数(例如SCSUBOCU )。

尽管UTF-32BEUTF-32LE是更简单的CES,但大多数与Unicode一起使用的系统都使用UTF-8 ,它与固定长度的ASCII和MAPS UNICODE代码指数向后退兼容,以章程的可变长度序列,或UTF-16BE,或UTF-16BE的可变长度序列向后与固定长度UCS-2BE兼容,并映射Unicode代码指向16位单词的可变长度序列。有关详细讨论,请参见Unicode编码的比较

最后,可能有一个高级协议,该协议提供了其他信息来选择Unicode字符的特定变体,尤其是在有区域变体中已在Unicode中“统一”为同一字符的情况。一个示例是XML属性XML:lang。

Unicode模型对其他系统使用术语“字符映射”,该系统将字符序列直接分配给一个字节序列,涵盖所有CCS,CEF和CES层。

Unicode代码点

在Unicode中,一个字符可以称为“ U+”,然后在十六进制中的编码点值。 UNICODE标准的有效代码点(代码空间)的范围为U+0000至U+10FFFF,包含在内,在17架飞机中分开,由数字0到16标识。在平面0中,称为基本多语言平面(BMP)。该平面包含最常用的字符。 u+10000到u+10ffff范围内的字符称为补充字符

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

特点 Unicode代码点 字形
拉丁a U+0041 Α
拉丁尖锐s U+00DF ß
汉去东方 U+6771
andand U+0026
倒的感叹号 U+00A1 ¡
部分标志 U+00A7 §

例子

考虑一串字母“ ab̲c𐐨” - 即,一个包含联合字符的unicode的字符串(U+0332 ̲)以及补充特征(U+10400𐐨)。该字符串具有几个在逻辑上等效的Unicode表示形式,但是每个单数表示都适合各种情况或要求范围:

  • 四个组成的字符
    a,,c,𐐀
  • 五个图形
    a,b,_,c,𐐀
  • 五个Unicode代码点
    U+0061,U+0062,U+0332,U+0063,U+10400
  • 五个UTF-32代码单元(32位整数值):
    0x00000061,0x00000062,0x00000332,0x00000063,0x00010400
  • 六个UTF-16代码单元(16位整数)
    0x0061,0x0062,0x0332,0x0063,0xD801,0xDC00
  • 九个UTF-8代码单元(8位值或字节
    0x61,0x62,0xCC,0xB2,0x63,0xF0,0x90,0x90,0x80

特别注意,𐐨用一个32位值(UTF-32),两个16位值(UTF-16)或四个8位值(UTF-8)表示。尽管这些形式中的每一个都使用相同的位数(32)代表字形,但实际数值字节值如何相关并不明显。

转码

由于使用了许多字符编码方法(以及对与存档数据的向后兼容性的需求),已经开发了许多计算机程序来将数据转换为在字符编码方案之间,这是一个称为反编码的过程。其中一些在下面引用。

跨平台

  • Web浏览器- 大多数现代Web浏览器都具有自动字符编码检测。例如,在Firefox 3上,请参见“视图/角色编码子菜单”。
  • ICONV - 一个程序和标准化的API转换编码
  • Luit - 将输入和输出的编码转换为运行的程序的程序
  • Unicode的国际组件- 一组C和Java库,用于执行Charset转换。 UCONV可以从ICU4C使用。

Windows

  • Encoding.convert - .NET API
  • MultibyTetoWideChar/widechartomultibyte - 从ANSI转换为Unicode&Unicode到ANSI

也可以看看

常见的字符编码