自然码输入法编码方案属于(自然码输入法编码方案属于 东师)

前言最近踩到了后端文档生成。本想写一篇相关实践的总结,突然意识到电子文档的魅力,尤其是“字符编码模型”。我在此进行研究,撰写此文。不了解Unicode、UTF-

前言

自然码输入法编码方案属于(自然码输入法编码方案属于 东师)

最近踩到了后端文档生成。本想写一篇相关实践的总结,突然意识到电子文档的魅力,尤其是“字符编码模型”。我在此进行研究,撰写此文。

不了解Unicode、UTF-8、UTF-16、GBK,不了解码位和码元概念,或者经常遇到乱码问题的小伙伴可以在这篇文章中找到答案。

简述字符编码

相信你一定很熟悉上面的场景(ω),这是一个经典的字符编码错误导致的乱码问题。解决方法也很简单,打开文件时指定正确的编码方式即可。如图所示,文本文件a.txt采用utf-8编码。指定打开和读取文本内容的编码方式,如下图所示。

解决方法很简单,但背后的知识并不简单,就是“字符编码”。众所周知,一个字符类型(char)的长度是1个字节,多个字符的数组(约定以[6]结尾)是一个字符串。问题来了。一个字节只能代表2,828 (256)个数字。怎么能代表比它大几百倍的汉字呢?上面用的utf-8是什么?为什么不指定就乱码了?

汉字表达起来很简单。一个字节不够,再来一个字节吧。用多个字节表示字符涉及到一些问题,比如如何使用几个字节,如何高效使用空,如何在灵活可扩展的同时表示足够大的范围。所以提出了以utf-8为代表的字符编码方式,告诉计算机如何解析字节流,转换成字符流。因为大多数字符编码方法彼此不兼容,所以通过使用不同的编码方案,很自然地会出现错误或将其解析为错误的内容。

维基百科中给出了如下定义:字符编码(英文:Character encoding)是将字符集中的字符编码成指定集合中的对象(例如,位模式、自然数序列、八位字节或电脉冲),使文本存储在计算机中,并通过通信网络传输。

概念可能不够具体。狭义的字符编码是对字符(包括英文字母、汉字等)进行编码。)转换成可以被计算机存储和解析的字节流。同时,它还支持从字节流中解析字符。这是将现实生活中使用的文字和符号进行建模,用计算机能理解的方式表达出来,便于计算机处理。

为了规范字符编码的过程,人们对编码设计的过程进行了划分,提出了字符编码的抽象架构模型,该模型由五层组成,解决了字符编码过程中的五个具体细节。接下来详细介绍。

字符编码模型

设计字符编码按顺序可分为以下五个步骤:

定义字符集:解决包含的字符范围的问题,声明都有哪些字符编码字符集:解决如何用数字信号唯一的表示字符集中的每个字符设计计算机保存字符编码用哪种数据类型以哪种规则保存:解决如何用某种数据类型描述字符编码后的数字信号确定保存字符编码所用的数据类型如何映射到字节序列:解决数据类型(用来描述字符编码的数字信号)在计算机中(用字节序列)的表示方法选择传输时合适的字节序列编码与压缩方案:解决描述字符串的字节序列在传输过程中的编码与压缩问题

根据上述五个步骤,定义:

字符编码模型=抽象字符表+编码字符集(CCS)+字符编码表(CEF)+字符编码方案(CES)+传输编码语法字符编码模型=抽象字符表+编码字符集(CCS)+字符编码表(CEF)+字符编码方案(CES)+传输编码语法

五层模型1. 抽象字符表(Abstract character repertoire)

抽象字符表定义了当前字符编码支持的所有抽象字符集。

抽象字符是指人们认为视觉上不同,逻辑上意义相同的一组实际字符。可以认为这个集合中的字符代表了相同的意思。第一层的意思是,一个汉字有楷、行、草、隶等多种形式,但都代表同一个汉字,如下图所示。另一层意思是,在Unicode中,西班牙语是由两个字符N和~组成的。虽然看起来是一个,但是有两个不同的意思。

抽象字符集的一些标准是封闭的,抽象字符集不会改变(包括ASCII、ISO 8859系列等。);有些标准是开放的,可以不断添加新的字符(比如Unicode)。

2. 编码字符集(CCS: Coded Character Set)

编码字符集在一级抽象字符集的基础上,给每个字符分配一个唯一的数字代码,使抽象字符可以用数字来表示。

编码字符集是一个映射过程,将抽象字符集中的每个字符一一映射到一个坐标上(如果是一维的,则为单个整数),每个映射的坐标(即数字编码)称为码点(也叫码点),每个字符所占的码点称为码点值。因此也可以称为:编码字符集是将抽象字符集中的每个抽象字符映射成一个码位值。

用来表示码位的坐标空之间的维数称为码室空,可以用一组数字、存储单元的大小或某些特殊形式来表示。比如:GB 2312汉字编码空可以表示为94×94;ISO-8859-1的代码空可以表示为8位或256位;使用行、列和平面的Unicode三维描述来表示码位值。

这里特别解释一下Unicode(统一码)编码字符集。每个Unicode字符代码可以表示为:U+6个十六进制数字,比如:& # 39;0'表示为& # 39; U000030 & # 39。采用Unicode平面+16位编码方式,每个平面的编码空为2 ^ 16(带& # 39; U000030 & # 39的最后四位,使用两个字节),共17个平面(使用& # 39; U000030 & # 39的前两位,用一个字节),理论上可以表示的字符数=平面数(17) ×平面码空大小(2 ^ 16)= 114112。七个平面编号为0-16(0x00-0x10),如下所示。

日常生活中常用的字符定义在平面0中,表示该平面的码位时可以省略前两位十六进制数的平面号。并不是平面中的每一个位置都定义了对应的字符,很多空都是保留的或者用于特殊用途。

每一个抽象字符在Unicode中都用一个唯一的、不可变的字符名来表示,比如Unicode中拉丁字母K的字符名是“拉丁大写字母K”,码位是004B。

3. 字符编码表(CEF: Character Encoding Form)

字符表将数字表示的码位值转换为整数值序列(由多个固定和有限长度的整数数据类型组成)。

用于表示码位的有限长整形是计算机表示字符编码(码位值)的单位,称为编码单位,简称符号。

定义字符编码表有两个步骤:

定义码元定义如何使用多个码元表示码点值的规则

定义的符号通常是8位(字节)的倍数。符号的存在规范了不同字符的存储方式,避免了一串字符中各种长度的混合表达。字节在计算机中的多重存储和处理也与存储、传输和处理的单位相匹配,与计算机中的数据类型相对应。

定义用符号表示码位值的规则,分为定长编码和变长编码。定长码是自身到自身的映射,比如ASCII码0-127,对应7 bit,直接用1字节表示。UTF-32是Unicode对应的定长编码方案,字节内容与码位一一对应。

可变长度编码根据某些规则将编码比特值映射到不同数量的符号序列。

UTF-8

这里,使用Unicode中最常见的字符编码表UTF-8进行解释。UTF-8是Unicode的边长码。码元为8位,用1-4个码元(字节)来表示一个字符。根据字符码位值的不同变化来表示长度。编码规则如下:

Unicode十六进制码位范围

UTF-8双星

0000 0000 - 0000 007F

0xxxxxxx

0000 0080 - 0000 07FF

110xxxxx 10xxxxxx

0000 0800 - 0000 FFFF

1110xxxx 10xxxxxx 10xxxxxx

0001 0000 - 0010 FFFF

11110 XXX 10 xxxxx 10 xxxxx 10 xxxxx 10 xxxxx

对于单字节字符,第一位设置为0,后7位对应于该字符的Unicode码位。因此,英文中的字符0-127与ASCII码完全相同。这意味着UTF-8与过去用ASCII编码的文件完全兼容。对于需要用N个字节表示的字符(n >: 1),第一个字节的前N位全部设置为1,第N+1位设置为0,剩余N-1个字节的前两位全部设置为10,剩余的二进制位用该字符的Unicode码位填充。UTF-16UTF-16使用16位(两字节)符号,编码规则为:基本平面的字符占用2字节,辅助平面的字符占用4字节。并且通过对基本平面中的U+D800-U+DFFF的空白进行编码来实现使用一个符号还是两个符号的确定。

辅助平面中有2个20字符位,所以至少需要20个二进制位来表示这些字符。UTF-16将这20个二进制位分成两半。前10位映射在U+D800和U+DBFF之间(空,大小为2 ^ 10,称为高位(H),后10位映射在U+DC00和U+DFFF之间(空,大小为2 ^ 10。这意味着辅助平面的字符被分割成两个基本平面字符。

第二层的编码字符集和本层的字符编码表之间是多对多的关系。一种编码方法也可以适用于多种字符集,如:EUC编码方法可以用于GB 2312或JIS X 0208(一种日语字符集编码标准);为什么一个字符集对应多种编码方式,比如Unicode对应UTF-8、UTF-16、UTF-32等编码方式,如下图所示。

例如,两个汉字“汉字”的Unicode码位值是0x6C49和0x5B57,可以用一个与符号对应的整型数组来表示,如下所示

4. 字符编码方案(CES: Character Encoding Scheme)

字符编码方案将符号映射到字节序列。

抽象字符的码位值可以用特定数据类型的符号来表示,但是由于这些数据类型可能需要多个字节来表示,所以我们还没有解决如何用字节序列来表示符号。符号映射是一个字节序列,即特定的整数类型映射到相应的字节序列。一般来说就是字节序,也就是大端小端(当然也有一些比较复杂的)。

大端:低位地址存储高位数据,高位地址存储低位数据。与人们一般的书写习惯一致,网络端需要使用大端。

小:低位地址存储低位数据,高位地址存储高位数据。

例如,数字0x0102在大端存储为[0x01,0x02],在小端存储为[0x02,0x01]。

在编程中,很多时候,我们不需要关系型的endian,而是直接使用特定的数据类型。作为操作系统或硬件的内部实现,端序对用户是透明的。但是,文本不仅需要在本地内存中读写,还需要存储在磁盘中,在多个异构系统中循环,这就要求字节序或者用来读取文本的字节序的一致性。因此,需要定义一个字符编码方案,以便在读写时显示符号的字节序列的一致性。

为了解决字节顺序的问题,通常有两种方案:

强制规定使用某种字节序。如网络传输强制要求网络字节序使用大端序。使用字节序标记说明当前使用的字节序。字符集编码一般采用这种方案。Unicode 编码方案中有个叫 BOM(Byte Order Mark)的东西,就是用来做这事的。

当然,当符号为单字节时,不存在字节顺序问题,比如UTF-8,这也是UTF-8被广泛使用的原因之一。然而,一些UTF-8文件也有BOM头,但这不是必需的。它仅用于标识文件是以UTF-8编码的。

5. 传输编码语法(transfer encoding syntax)

传输语法用于处理第四层字符编码方案提供的字节序列,主要包括转换传输形式和压缩字节序列。

变换形式是指将字节序列的值映射到一组更受限制的取值范围,以满足传输环境的约束。例如,电子邮件传输采用Base64或quoted-printable,将8位字节编码为7位数据。

压缩字节序列是指一些无损字节序列压缩技术。例如LZW或笔画长度编码。

模型综述

从整体上看,字符编码模型是从人类理解的抽象字符到计算机实际表示、存储和传输的字符的数据形式的建模过程。

第一层抽象字符表是对人类所理解的抽象字符的总结,定义了抽象字符的范围。每个抽象字符在不同的上下文中可能有不同的字形(不同的书写风格)和不同的含义,但字符本身的逻辑是相同的,用字符名来唯一标识字符。

第二个编码字符集是抽象字符数,用数学形式表示抽象字符,类似于模拟电和数字电的关系,因为只有数字才能进一步存储在计算机中。但需要注意的是,这一层不涉及计算机,数学数也是人类意义上的数。然而,将形式符号抽象成数学数字是用计算机对现实事务建模的关键步骤。

三级字符编码形式是真正用计算机表示字符的第一步。这里用计算机的抽象数据类型(符号)来表示人类字符的抽象描述(数学编码)。

第四层字符编码方案进一步将由计算机的抽象数据类型表示的字符映射到字节流,即计算机的真实底层表示。在这个层面上,字符已经完全转化为计算机表征,计算机可以基于上述模型栈(其顺序处理形式可以理解为栈)对字符进行读、写或其他操作,在计算机底层表征和人类抽象字符之间进行转换。

第五层传输编码语法是对计算机底层数据流的附加处理,以提高传输效率或满足传输要求。

上述字符编码模型可以进一步概括为计算机建模的一个总体思路:定义真实的东西,对事物建模,用计算机数据类型表示,用计算机底层字节序列表示,优化字节序列。

字符与字形

在前面的学习中,我们已经知道了通过字符编码模型将抽象字符转化为计算机底层数据结构的过程,这个过程似乎已经完成。但是请重新审视你正在阅读的课文中的人物,回忆一下你刚刚学过的内容。字符编码模型是从你看到的字符到底层计算机表示的完整链接吗?

没错,字形不见了。在抽象字符集中,我们强调字符集中的字符是逻辑抽象字符,而不是我们直接看到的字符。每个字符都有各种不同书写风格的字形。那么,现在怎么表示字形呢?

字形描述就是字体。字体描述了字符的形状,并告诉计算机如何“绘制”字符。一般有零散的点和向量。

因为本文重点介绍的是字符编码模型,所以这里就不做更详细的介绍了。

举个实践例子

s:= & # 34;嗨& # 34;fmt。println(& # 34;符文:& # 34;)for _,r := range s {fmt。printf(& # 34;% v & # 34,r)} fmt。println(& # 34; n字节数:& # 34;)对于I:= 0;我& lt镜头;i++ {fmt。printf(& # 34;% v & # 34,s[i])}fmt。println(& # 34; n 伦:& # 34;,len(s))问一下,上面的go代码输出结果是什么?

符文:104 105 20320 22909 32字节:104 105 228 189 160 229 165 189 32 len(s):9你猜对了吗?

这是一个角色符文和字节序列的对比使用场景。For-range遍历字符串中每个字符的码位值。但是字符串实际上是存储在字节数组中的,长度已经被len函数索引的索引都是通过读取字符底部的字节序列来表示的。也就是说,go中的字符串本质上是一个字节数组,只是存储了字符的底层字节表示,但它提供了将字节数组解析成字符的视图,这样我们就可以遍历并读取字符串中的字符。

在python中,还可以通过编码和解码在字符串和字节(字节数组)之间进行转换。

后记

字符编码是电子文件和程序设计的基础。只有了解字符编码,才能轻松使用最常用的数据类型之一——字符串。

之后继续学习电子文档,写两篇关于pdf、word、xlsx等场景文档的生成、修改和底层格式设计的文章。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/358347.html

发表回复

登录后才能评论