字符编码:unicode,ascii,utf-8.

最近一直碰到乱码问题,就想仔细的了解下字符编码,UNICODE,ASCII,UTF-8这些东西的区别.主要看了wikipedia.
基于冯诺依曼体系的结构的计算的一个基本思想是,计算机用二进制做为基本执行单元(二进制可对应于开或关,通路或断路,正偏或反偏等),
这样,一个二进制位(具体实现方式比如电子管的通断路)就可以表示一种状态,把几个二进制位组合在一起就可以表示一个更为复制的状态,
然后再计算机的内存中,把起到控制作用的二进制序列,起到字符存储作用的二进制序列,起到中转或临时作用的二进制序列分开存放,然后使
得这些序列(实际上是某个元件的2中状态)按一定顺序执行下去,需要哪部分的二进制序列就跳转过去,这样计算机就能够运行,并且人们可以通过控制二进制序列来控制计算机按自己的目的运行(这才叫技术)...
基于二进制或者说直接与二进制打交道的有指令集->汇编语言(汇编语言编译器);二进制序列(机器语言)->指令集->高级语言.其他如采用虚拟机的就不说了.
==========================================分割================================================
到正题.
    上文说的字符需要存储在计算机中,那么,要怎么存? 英语可能还比较好存,26个字母,加上其他的的转义字符(空格回车等)我给他们每个字符对应一个数,如0-127,那就可以存储了.(ASCII)
    而对于非拉丁语呢? 如中文,日文,韩文等? 此时拉丁语所包含的字节数明显不够用了,需要一个更大的集合来包含这些字符,于是有了UNICODE.
    看下下面维基关于字符编码的说明.
-------------------------------------------------------------分割--------------------------------------------------------------------------
(1).字符编码

    字符编码英语Character encoding)、字集码是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数串行、8位组或者电脉冲),以便文本计算机中存储和通过通信网络的传递。常见的例子包括将拉丁字母表编码成摩斯电码ASCII。其中,ASCII将字母、数字和其它符号编号,并用7比特二进制来表示这个整数。通常会额外使用一个扩充的比特,以便于以1个字节的方式存储。(wiki).

现代编码模型:

统一码通用字符集所构成的现代字符编码模型则没有跟从简单字符集的观点。它们将字符编码的概念分为:有哪些字符、它们的编号、这些编号如何编码成一系列的“码元”(有限大小的数字)以及最后这些单元如何组成八位字节流。区分这些概念的核心思想是创建一个能够用不同方法来编码的一个通用字符集。为了正确地表示这个模型需要更多比“字符集”和“字符编码”更为精确的术语表示。在Unicode Technical Report (UTR) #17中,现代编码模型分为5个层次,所用的术语列在下面:

  1. 抽象字符表(Abstract character repertoire)是一个系统支持的所有抽象字符的集合。字符表可以是封闭的,即除非创建一个新的标准(ASCII和多数ISO/IEC 8859系列都是这样的例子),否则不允许添加新的符号,;字符表也可以是开放的,即允许添加新的符号(统一码和一定程度上代码页是这方面的例子)。特定字符表中的字符反映了如何将书写系统分解成线性信息单元的决定。例如拉丁、希腊和斯拉夫字母表分为字母、数字、变音符号、标点和如空格这样的一些少数特殊字符,它们都能按照一种简单的线性串行排列(尽管对它们的处理需要另外的规则,如带有变音符号的字母这样的特定串行如何解释——但这不属于字符表的范畴)。为了方便起见,这样的字符表可以包括预先编号的字母和变音符号的组合。其它的书写系统,如阿拉伯语和希伯莱语,由于要适应双向文字和在不同情形下按照不同方式交叉在一起的字形,就使用更为复杂的符号表表示。
  2. 编码字符集(CCS:Coded Character Set)是将字符集C中每个字符映射到1个坐标(整数值对:x, y)或者表示为1个非负整数N。字符集及码位映射称为编码字符集。例如,在一个给定的字符表中,表示大写拉丁字母“A”的字符被赋予整数65、字符“B”是66,如此继续下去。多个编码字符集可以表示同样的字符表,例如ISO-8859-1和IBM的代码页037和代码页500含盖同样的字符表但是将字符映射为不同的整数。由此产生了编码空间(encoding space)的概念:简单说就是包含所有字符的表的维度。可以用一对整数来描述,例如:GB 2012的汉字编码空间是94 x 94。可以用一个整数来描述,例如:ISO-8859-1的编码空间是256。也可以用字符的存储单元尺寸来描述,例如:ISO-8859-1是一个8比特的编码空间。编码空间还可以用其子集来表述,如行、列、面(plane)等。编码空间中的一个位置(position)称为码位(code point)。一个字符所占用的码位称为码位值(code point value)。1个编码字符集就是把抽象字符映射为码位值。
  3. 字符编码表(CEF:Character Encoding Form),也称为"storage format",是将编码字符集的非负整数值(即抽象的码位)转换成有限比特长度的整型值(称为码元code units)的串行。这对于定长编码来说是个到自身的映射(null mapping),但对于变长编码来说,该映射比较复杂,把一些码位映射到一个码元,把另外一些码位映射到由多个码元组成的串行。例如,使用16比特长的存储单元保存数字信息,系统每个单元只能够直接表示从0到65,535的数值,但是如果使用多个16位单元就能够表示更大的整数。这就是CEF的作用,它可以把Unicode从0到140万的码空间范围的每个码位映射到单个或多个在0到65,5356范围内的码值。最简单的字符编码表就是单纯地选择足够大的单位,以保证编码字符集中的所有数值能够直接编码(一个码位对应一个码值)。这对于能够用使用八比特组来表示的编码字符集(如多数传统的非CJK的字符集编码)是合理的,对于能够使用十六比特来表示的编码字符集(如早期版本的Unicode)来说也足够合理。但是,随着编码字符集的大小增加(例如,现在的Unicode的字符集至少需要21位才能全部表示),这种直接表示法变得越来越没有效率,并且很难让现有计算机系统适应更大的码值。因此,许多使用新近版本Unicode的系统,或者将Unicode码位对应为可变长度的8位字节串行的UTF-8,或者将码位对应为可变长度的16位串行的UTF-16
  4. 字符编码方案(CES:Character Encoding Scheme),也称作"serialization format"。将定长的整型值(即码元)映射到8位字节串行,以便编码后的数据的文件存储或网络传输。在使用Unicode的场合,使用一个简单的字符来指定字节顺序是大端序或者小端序(但对于UTF-8来说并不需要专门指明字节序)。然而,有些复杂的字符编码机制(如ISO/IEC 2022)使用控制字符转义串行在几种编码字符集或者用于减小每个单元所用字节数的压缩机制(如SCSUBOCUPunycode)之间切换。
  5. 传输编码语法(transfer encoding syntax),用于处理上一层次的字符编码方案提供的字节串行。一般其功能包括两种:一是把字节串行的值映射到一套更受限制的值域内,以满足传输环境的限制,例如Email传输时Base64或者quoted-printable,都是把8位的字节编码为7位长的数据;另一是压缩字节串行的值,如LZW或者进程长度编码等无损压缩技术。

高层机制(higher level protocol)提供了额外信息,用于选择Unicode字符的特定变种,如XML属性xml:lang

字符映射(character map)在Unicode中保持了其传统意义:从字符串行到编码后的字节串行的映射,包括了上述的CCS, CEF, CES层次。

术语字符编码(character encoding),字符映射(character map),字符集(character set)或者代码页,在历史上往往是同义概念,即字符表(repertoire)中的字符如何编码为码元的流(stream of code units)–通常每个字符对应单个码元。

码元(Code Unit,也称“代码单元”)是指一个已编码的文本中具有最短的比特组合的单元。对于UTF-8来说,码元是8比特长;对于UTF-16来说,码元是16比特长;对于UTF-32来说,码元是32比特长[1]。码值(Code Value)是过时的用法。

代码页通常意味着面向字节的编码,但强调是一套用于不能语言的编码方案的集合.著名的如"Windows"代码页系列,"IBM"/"DOS"代码页系列.

IBM的字符数据表示体系(Character Data Representation Architecture - CDRA)与编码字符集标识符(coded character set identifiers - CCSIDs) 常常把charset, character set, code page, or CHARMAP等类似意义的术语混用.

Unix或Linux不使用代码页概念,它们用charmap,比locales具有更广泛的含义.

与上文的编码字符集(Coded Character Set - CCS)不同,字符编码(character encoding)是从抽象字符到代码字(code word)的映射. HTTP(与MIME)的用法中,字符集(character set)与字符编码同义,但与CCS不是一个意思.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------
    最浅显的理解,字符编码就是把所有的文字都对应一个整数,如 0-65536就可以表示65536个字符.

(2)ASCII,UNICODE

    如上句,把文字对应成整数,那么哪个字符对应那个哪个整数就涉及到一个标准问题.

    ASCII(pronunciation: /ˈæski/ ASS-kee[1]American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以部分支持其他西欧语言,并等同于国际标准ISO/IEC 646
 简单的说,ASCII是美国人搞出来的适合于英语环境的一个字符编码集.

    Unicode是为了解决传统的字符编码方案的局限而产生的,例如ISO 8859所定义的字符虽然在不同的国家中广泛地使用,可是在不同国家间却经常出现不兼容的情况。很多传统的编码方式都有一个共同的问题,即容许电脑处理双语环境(通常使用拉丁字母以及其本地语言),但却无法同时支持多语言环境(指可同时处理多种语言混合的情况)。

Unicode编码包含了不同写法的字,如“ɑa”、“強/强”、“戶/户/戸”。然而在汉字方面引起了一字多形的认定争议(详见中日韩统一表意文字主题)。

在文字处理方面,统一码为每一个字符而非字形定义唯一的代码(即一个整数)。换句话说,统一码以一种抽象的方式(即数字)来处理字符,并将视觉上的演绎工作(例如字体大小、外观形状、字体形态、文体等)留给其他软件来处理,例如网页浏览器或是文字处理器。

目前,几乎所有电脑系统都支持基本拉丁字母,并各自支持不同的其他编码方式。Unicode为了和它们相互兼容,其首256字符保留给ISO 8859-1所定义的字符,使既有的西欧语系文字的转换不需特别考量;并且把大量相同的字符重复编到不同的字符码中去,使得旧有纷杂的编码方式得以和Unicode编码间互相直接转换,而不会丢失任何信息。举例来说,全角格式区段包含了主要的拉丁字母的全角格式,在中文、日文、以及韩文字形当中,这些字符以全角的方式来呈现,而不以常见的半角形式显示,这对竖排文字和等宽排列文字有重要作用。

    于是,unicode是一个适合几乎所有语言环境的字符集.
    中文系统ASCII的实现为GB2312或Big5编码.UNICODE的最常见的是utf-8.
 
(3) utf-8
    如上,unicode规定了一系列字符和一系列整数的对应关系,但是,并没有规定具体怎么实现.
    比如,现在的字符集是0-216.,那么,我是全部用2字节(16位)来存储呢,还是部分用1字节部分2字节.显然,对于编码范围较小的环境是可行且方便的如UTF-16就是每个字符都占用2个字节.但在纯拉丁文环境下这会造成存储空间的浪费,此时ASCII编码是最合适的.对于编码范围较大(字符数较多,如中文)的采用UTF-16甚至UTF-32也是可行的.
    而对于中文,英文的混合环境,最合适的是采用变长编码,即在ASCII字符集内的字符还是保持其编码值不变,并且用1字节(8位)表示,对于中文则用2字节(16位)表示,这样可以最大程序的节省存储空间,这就是UTF-8编码.
    当然,隐藏了很多细节.具体可见wiki.http://zh.wikipedia.org/wiki/Unicode

(4)小端,大端

    字符在计算中按照对于的字符编码存储,但是标准并没有规定怎么存储,如二进制为00000001的二进制数,计算机可能存储为00000001也可能是10000000.这就是小端和大端的区别.
    如果最低有效字节最高有效字节的前面,则称小端序;反之则称大端序。在网络应用中,字节序是一个必须被考虑的因素,因为不同机器类型可能采用不同标准的字节序,所以均按照网络标准转化
  例如假设上述变量x类型为int,位于地址0x100处,它的十六进制为0x01234567,地址范围为0x100~0x103字节,其内部排列顺序依赖于机器的类型。大端法从首位开始将是:0x100: 01, 0x101: 23,..。而小端法将是:0x100: 67, 0x101: 45,..。

    

 




I see I come I conquer.
原文地址:https://www.cnblogs.com/yTPety/p/3524224.html