什么是字符编码?编码和字符集是什么

2024-08-05 03:45:19 0

什么是字符编码?编码和字符集是什么

大家好,今天小编来为大家解答以下的问题,关于字符编码,什么是字符编码这个很多人还不知道,现在让我们一起来看看吧!

本文目录

什么是字符编码

字符编码(英语:Character encoding)、字集码是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数序列、8位组或者电脉冲),以便文本在计算机中存储和通过通信网络的传递。常见的例子包括将拉丁字母表编码成摩斯电码和ASCII。其中,ASCII将字母、数字和其它符号编号,并用7比特的二进制来表示这个整数。通常会额外使用一个扩充的比特,以便于以1个字节的方式存储。在计算机技术发展的早期,如ASCII(1963年)和EBCDIC(1964年)这样的字符集逐渐成为标准。但这些字符集的局限很快就变得明显,于是人们开发了许多方法来扩展它们。对于支持包括东亚CJK字符家族在内的写作系统的要求能支持更大量的字符,并且需要一种系统而不是临时的方法实现这些字符的编码。

编码和字符集是什么

要搞明白二者,首先要明确,计算机识别的是二进制的机器码,而人说的是自然语言,类比生活中的中文和英文的交流,需要对应翻译,人和计算机之间想要进行信息的交换也需要让 计算机能听懂人话,人能看懂计算机的语言,同样需要翻译编码就是定义如何自然语言的字符"翻译"为二进制数的过程字符集就是自然语言字符的集合,不同的字符集支持的字符范围也不同,这些字符通过编码对应为唯一的二进制数后会形成一个表格.想了解编码和字符集这种计算机基础知识点推荐看社区:黑马程序员---》软件测试板块,对话框可以领取课程大纲+视频+ppt+源码

计算机字符编码有哪些

计算机常用的编码有:ASCII码汉字编码

字符编码就是以二进制的数字来对应字符集的字符,目前用得最普遍的字符集是ANSI,对应ANSI字符集的二进制编码就称为ANSI码,DOS和Windows系统都使用了ANSI码,但在系统中使用的字符编码要经过二进制转换,称为系统内码。                                                                                  1.汉字内码:ANSI码是单一字节(8位二进制数)的编码集,最多只能表示256个字符,不能表示众多的汉字字符,各个国家和地区在ANSI码的基础上又设计了各种不同的汉字编码集,以能够处理大数量的汉字字符。这些编码使用单字节来表示ANSI的英文字符(即兼容ANSI码),使用双字节来表示汉字字符。由于一个系统中只能有一种汉字内码,不能识别其它汉字内码的字符,造成了交流的不便。                                                                                                                                              2.GB码:GB码是1980年国家公布的简体汉字编码方案,在大陆、新加坡得到广泛的使用,也称国标码。国标码对6763个汉字集进行了编码,涵盖了大多数正在使用的汉字。                                  3.GBK码:GBK码是GB码的扩展字符编码,对多达2万多的简繁汉字进行了编码,简体版的Win95和Win98都是使用GBK作系统内码。                                                                                           4.BIG5码:BIG5码是针对繁体汉字的汉字编码,目前在台湾、香港的电脑系统中得到应用。        5.HZ码:HZ码是在Internet上广泛使用的一种汉字编码。                                                            6.ISO -2022CJK码:IOS-2022是国际标准组织(ISO)为各种语言字符制定的编码标准。采用二个字节编码,其中汉语编码称ISO- 2022 CN,日语、韩语的编码分别称JP、KR。一般将三者合称CJK码。目前CJK码主要在Internet网络中使用。                                                                         7.Unicode码:Unicode码也是一种国际标准编码,采用二个字节编码,与ANSI码不兼容。目前,在网络、Windows系统和很多大型软件中得到应用。

字符编码简述

众所周知,java中如果要计算一个字符串的长度,可以直接利用String的length方法。如下:

显然,这里的length方法计算的字符数,一个英文字母按一个字符计算,一个中文汉字也是按照一个字符进行计算的。 不过,如果想要获取字符串的字节数呢?String依然提供了现成的方法供我们使用,如下所示:

这里,可以看到几个注意点:

先来看第一点,也是本文主要想讨论的问题:UTF-8、GBK的区别是什么,为什么会导致最终获取的字节数不一样?

要解答上面的问题,需要先知道GBK和UTF-8分别是什么。 简单的说,GBK和UTF-8是两种字符的编码方式。那么,问题又来了,什么是字符的编码方式呢?除了GBK和UTF-8,有没有其他的编码方式呢?其中的区别又在哪里?

关于字符的编码方式,姑且可以简单的理解为,将一个字符表示成一串bit流的规则(这个说法是不太准确的,下文会有详细解释)。比如说,UTF-8就是一种非常常用的字符编码方式,“汉”字以UTF-8的规则计算后表示出来的bit流就是“11100110 10110001 10001001”。 有些时候,编码方式,还会被称为编码规则、编码方案。

实际上,从计算机不再单纯地拿来进行数字计算开始,字符的编码方式就一直在不断的演进,现在就借着这一段历史,来对包括GBK、UTF-8在内的几种常见字符编码方式进行下介绍。

计算机刚出世的时候,美国人为了交流通信方便,约定了一套字符编码方式,就是ASCII码。 ASCII全称为American Standard Code for Information Interchange,即美国信息互换标准码。

ASCII码的字符集中包含了26个英文字母、10个数字(0-9)、一些常见的符号(@、#、!),基本能够满足在英语环境下的需求。ASCII字符集里面只有128个字符,每个字符都有一个编号,也就是0-127。而当时大家已经习惯于用8个bit来表示一个字节,所以干脆取一个字节来表示一个字符。其中,最高位置为0,其他位全部用上,总共128个位置,刚好能够与ASCII字符集一一对应。 举个例子,在ASCII码中,‘A’对应的编号是65,用一个字节表示就是“01000001”。

这里对引入的两个新概念做下解释: 字符集 :字面上理解就是字符的集合。 编号字符集 :指带有数字编号的字符集合,有时候也简称为字符集。例如:,在此字符集中,包含三个字符:a、b、c,并且其编号分别为1,2,3。

不过,后来计算机传到了欧洲,不少欧洲国家的语言使用ASCII码无法完整地进行表示,比如德语、法语。上文可以看到,在ASCII编码中,一个ASCII字符,是用一个字节来表示的。一个字节实际上能够表示256个数字,也就至少能够表示256个字符,而ASCII字符集只有128个字符。所以这时候出现了多种基于ASCII的编码方式。大家的基本思路都是一样的:还是使用一个字节表示一个字符,0-127依然用来表示ASCII字符集(字符编号与ASCII码保持一致),128-255拿来表示自己语言中的特殊字符。

显然,这么搞出来的多个编码方式互不兼容,大家会很痛苦。所以最后出现了两套统一的编码方案,能够对欧洲各国的字符都进行支持。这两套编码方案分别是:EASCII(Extended ASCII)字符编码方案,ISO/IEC 8859字符编码方案。

这两套方案也是沿用上面的思路:0-127依然用来表示ASCII字符集(字符编号与ASCII码保持一致),128-255用来表示欧洲各国的特殊字符(这部分字符集又被称为扩展字符集)。

由于在这两种编码方案中,ASCII字符集中的字符,保留了与ASCII码相同的字符编号,所以 这两种编码方案都是对ASCII编码完美兼容的

不过,与ASCII、EASCII属于单个独立字符集不同,ISO/IEC 8859是一组字符集的统称。其下共有15个字符集,即ISO/IEC 8859-n,n=1,2,3 …… 15,16(其中12未定义,所以共15个)。

到现在为止,EASCII已经很少有人用了,ISO/IEC 8859却是被广泛使用,其中ISO/IEC 8859-1被使用的最为普遍。而ISO/IEC 8859-1又被简称为ISO 8859-1,而且它还有一个Latin-1(也写作Latin1)的简称。

终于,计算机来到了中国。如上文所述,仿照ASCII码的规则,1个字节最多也就只能表示256个字符。但是,中国汉字有几万个,常用字就有几千个,这样的话,1个字节是完全不够用的。所以,当时的全国信息技术标准化技术委员会搞了一套自己的编码方案:用两个字节表示一个字符。这就是GB系列编码。“GB”是“国标”的拼音首字母缩写,意为“国家标准”。

最早的GB编码就是GB2312,收录了6763个汉字和682个符号,基本能够满足日常需求。 GB2312规定,一个汉字的编号必须大于127,并且编号大于127的字符必须用两个字节来表示。而0-127,仍然用来表示之前的ASCII字符集,这部分字符的编号依旧与ASCII码保持一致,并且只有一个字节来表示。

所以,GB2312对ASCII码是完全兼容的。不过GB2312对ISO是不兼容的,因为它舍弃了ISO中128-255之间的字符映射。 同时,也可以认为,在GB2312中,英文字符只占一个字节,而中文字符会占两个字节。

而计算机在依照GB2312编码进行字符识别时,会先判断第一个字节的第一个bit位是否为0,如果是,则读取1个字节,进行编码解析;如果不是,则读取两个字节,进行编码解析。

此外,当时出于种种原因考虑,GB2312对ASCII码中的西文字母、数字、标点等特殊符号进行了重新编码,用两个字节来进行表示。所以,这类字符在GB2312中就有了两种编码表示,其中小于128的编码(用1个字节表示),就被称为半角字符,大于128的编码(用2个字节表示),就被称为全角字符。

到目前为止,由于当时导致全角字符出现的历史原因已经不再存在,所以只有很少的一些全角字符还在使用(比如中文的逗号,问号,感叹号,空格等),其他的许多全角字符已经很少用了。

虽然GB2312能够满足基本的日常需求,但是毕竟收录的汉字还是太少,繁体字、生僻字是不包含在GB2312字符集中的。由此,有关部门对GB2312进行了扩展,推出了GBK编码。

GBK与GB2312基本一致,都是使用两个字节来表示汉字。不过有一点不一样:在GB2312中,表示汉字的两个字节中,其首位必须都是1;而在GBK中,只要求第一个字节(高字节)的首位为1,对于第二个字节(低字节),没做要求。当然,如果首位为0,都是用来表示ASCII字符集里的内容。

GBK可以认为是对GB2312的扩展,其对GB2312是完美兼容的。所以,GBK对ASCII码也是完美兼容的。

GB18030是对GBK的进一步扩展,在扩展现有汉字的基础上,收录了数千个少数民族的字符。其由中国国家质量技术监督局于2000年3月17日推出,用以取代GBK。

GB18030同样保持向下兼容,其对GBK、GB2312、ASCII编码完美兼容。

诸如GB2312、GBK、GB18030之类的编码格式,被程序员们称为DBCS(Double Byte Charecter Set:双字节字符集)。在DBCS的标准里,英文字符用一个字节表示,并且这个字节的第一位必然为0(英文字符对应的字号小于128);中文字符用两个字节表示,第一个字节的第一位必然为1。

如上文所述,在计算机的传播途中,为了兼容各地的语言,出现了许许多多的编码方案。但是遗憾的是,这些编码方案互不兼容,直接影响到了信息的传播,这也催生了能够兼容全球各种字符的统一编码方案的出现。

历史上存在两个独立的尝试创立单一字符集的组织:

不过在1991年前后,两个项目组发现没必要存在两个不兼容的字符集,所以它们开始合并双方成果,约定使用统一的编码表。从Unicode 2.0开始,Unicode项目采用了与ISO 10646-1相同的字库与字码,ISO也承诺,ISO将不会替超出U+10FFFF的UCS-4编码赋值,以使得两者保持一致(UCS的概念下文会有详述,此处不必过于关注)。

目前,这两个项目组仍独立存在,并独立地发布各自的标准,不过二者约定保持双方的标准码表兼容,并共同调整任何未来的扩展。

ISO 10646标准,只是一个简单的字符集表。它定义了一些编码的别名,指定了一些与标准有关的术语,并包括了规范说明,指定了怎样使用UCS链接其他ISO标准的实现,比如ISO/IEC 6429和ISO/IEC 2022。还有一些与ISO紧密相关的,比如ISO/IEC 14651是关于UCS字符串排序的。

Unicode标准,额外定义了许多与字符有关的语义符号学内容,并详细说明了绘制某些语言(如阿拉伯语)表达形式的算法、处理双向文字(比如拉丁文和希伯来文的混合文字)的算法、排序与字符串比较所需的算法等。

在书写Unicode编码时,规定以十六进制数来进行表示,并需要加上“U+”前缀。比如“汉”字的Unicode编码为“U+6C49”。

为了能够更方便地介绍后续的内容,这里需要先解释清楚几个名词(个人认为这几个概念有助于理解后续的内容,如果不想看,可以直接跳过此节)。 编号字符集(CCS:Coded Character Set) :指带有数字编号的字符集合。上文已经介绍过了。 字符编码方式(CEF:Character Encoding Form) :将字符集的数字编号转换为字节流的规则。

还是上文中的例子,Unicode字符集中的“汉”字,在Unicode字符集中的编号是0x6C49,在UTF-8编码中,需要使用3个字节来表示,表示成二进制则是“11100110 10110001 10001001”(UTF-8的具体编码规则,下文会有详述)。 在这个例子中,Unicode就是所谓的编号字符集(CCS),UTF-8编码便是字符编码方式(CEF)。

实际上,在unicode字符集出世之前,字符集与编码方式往往是耦合在一起的,一套字符集往往也只有一套编码规则,这两个概念也没必要严格区分,人们也经常进行混用。比如ASCII码既可以认为是一套字符集,也可以认为是一种字符编码方式。

但是,Unicode字符集出现之后,字符集和编码方式被分离解耦了。此时,一套字符集可能有多套的编码规则,我们所熟知的UTF-8、UTF-16就是建立在Unicode字符集上的字符编码方式。

编码规则大致上可以分为两类:直接映射与间接映射。 直接映射 ,是指字符在字符集中的数字编号与编码后的编码串是一样的。比如ASCII字符集中,‘A’对应的字符编号是65,换算成二进制为“1000001”,按照ASCII码编码后,用一个字节来表示,就是“01000001”,也就是十进制中的65。编码前后,其实可以视为是一样的。 间接映射 ,就是字符在字符集中的数字编号与编码后的编码串不一定一样。还是上面的例子,unicode字符集中“汉”字的字符编号为0x6C49,如果换算成二进制就是“01101100 01001001”,但是UTF-8编码后要用三个字节来表示,表示成二进制就是“11100110 10110001 10001001”。编码前后,数值不一样。

其实,Unicode出现之前,大家一直用的都是直接映射,编码前后数值是一样的,这也是一直没有明确区分字符集和编码方式这两个概念的一个原因。

解释清楚了这几个概念,下面我们继续:

UCS全称为“Unicode Character Set”,是由ISO制定的ISO 10646标准所定义的标准字符集。 UCS又称“Universal Multiple-Octet Coded Character Set”,译为通用多八位编码字符集。 相对应的,Unicode项目所使用的标准字符集通常被称为Unicode字符集。

如上文所述,Unicode 2.0发布时,Unicode字符集与UCS字符集基本保持了一致,之后虽然二者独立存在,但是一直在保持互相的兼容。

在ISO与unicode合并之前,ISO就有一套字符编码模式,也就是UCS-2。 UCS-2的规则就是用两个字节来表示字符集中的字符,并且它使用的是直接映射的方式。所以可以简单理解为,UCS-2就是将字符的数字编号直接转化为二进制,然后用两个字节来进行存储。 与ASCII类似,此时的UCS-2其实可以视为一套字符集,也可以视为一套编码规则。

UCS-2用两个字节来表示一个字符,所能容纳的字符数量为2^16 = 65536个。 在ISO与Unicode合并字符集之后,双方约定字符集需要容纳的字符数量远远超过65535个(到目前为止,Unicode字符集可容纳的字符量为2^16 * 17 = 1114112个),此时UCS-2显然不够用了,所以ISO推出了新的规则,就是UCS-4.

UCS-4与UCS-2基本一样,唯一的不同点是,UCS-4使用4个字节来表示一个字符。 同样,UCS-4可以认为是一套字符集,也可以认为是一套编码规则。

在有些文章里,UCS-4有广义和狭义两种含义,广义上UCS-4包含UCS-2,狭义上不包含。个人理解,在指代字符集的时候,UCS-4包含UCS-2,但是在指代编码规则时,UCS-4不包含UCS-2。

UCS-2全称2-byte Universal Character Set,直译为2字节通用字符集。 UCS-4全称4-byte Universal Character Set,直译为4字节通用字符集。

注意:UCS-2和UCS-4组成的UCS字符集,都可以采用UTF-8、UTF-16、UTF-32进行编码。所以UCS-2与UTF-16并不等同,UCS-4与UTF-32也不等同。

如上文所述,ISO与Unicode合并之后,ISO推出了UCS-4。但是Unicode推出的却是另外一套编码规则:UTF-16.

UTF-16源于UCS-2,但是与UCS-2不太一样。UCS-2属于定长编码方式,永远使用两个字节来表示一个字符。而UTF-16属于变长编码方式,对于UCS-2字符集中的字符(0x0000~0xFFFF)使用2个字节来表示,对于UCS-4字符集中除开UCS-2里的字符(0x10000~0x10FFFFF),使用4个字节来表示。

UTF-16的编码规则属于间接映射。对于UCS-2字符集里面的内容,保持字符编号与生成的编码串相同,但是对于UCS-4中的其他字符(指除开UCS-2中的字符),字符编号与最终的编码串并不相同。这里采取了一套计算算法:代理机制。不过本文对此不做深究。

虽然UTF-16能够满足需求,但是一来对于ASCII字符集中的字符,UTF-16仍然需要使用两个字节来存储(这样会有一个字节的空间被浪费),并且ASCII中的字符,其UTF-16编码的第一个字节将永远是0x00,而C语言中又因为会将此字节视为字符串末尾导致字符串无法正常解析。所以UTF-16刚推出的时候,就受到了很多的抵制。

由此,UTF-8出现了。

UTF-8也是一种变长编码方式,它使用1到4个字节来表示一个字符。 字符编号为0~127(十进制)的字符,使用一个字节进行表示。 字符编号为128~2047(十进制)的字符,使用两个字节进行表示。 字符编号为2048~65535(十进制)的字符,使用三个字节进行表示。 字符编号为65536~2097151(十进制)的字符,使用四个字节进行表示。

UTF-8和UTF-16,都属于间接映射。也就是说,字符编号与最终的编码并不完全是一样的。 实际上,UTF-8的编码规则如下:

还是上文中的例子,Unicode字符集中的“汉”字,字符编号以16进制表示为“0x6C49”,换算成十进制就是27721,所以需要使用三个字节进行表示。而“0x6C49”换算成二进制就是“110110001001001”,代入上图中三字节的编码规则(“1110xxx 10xxxxxx 10xxxxxx”),最终得到的就是"1110110 10110001 10001001"。

当然,对于ASCII字符集里面的字符(字符编号小于128),UTF-8只需要一个字节即可表示。与UTF-16的两个字节相比,空间利用率更高(同样,在进行数据传输时,效率也更高)。 也因此,UTF-8对于ASCII码属于完美兼容,而UTF-16只能算是间接兼容(毕竟多了一个字节,解析的时候还需要进行转化)。考虑到计算机世界里ASCII字符的广泛性,这一点意义重大。 顺便说一句,虽然上面并没有介绍UTF-16的代理机制,但是可以说明的是,这个代理机制的算法要比UTF-8的算法更加复杂,一定程度上也导致了UTF-16进行编码和解码需要耗费更多的资源。

此外,可以看到,UTF-8编码产出的字节,都带有固定的前缀。这样做有几个好处: 第一,字符使用UTF-8编码之后,第一个字节的前面的几位,可以明确标识出来,此字符需要几个字节才能表示出来。这样的话,解码程序在读入每一个字节的时候,就能够知道当前字节是否为一个字符的首字节;如果是首字节的话,立刻就能知道还需要读入几个字节才能解析出来这个字符。 第二,字符经UTF-8编码之后,生成做到多个字节中,第一个字节的固定前缀与后续字节的固定前缀都不一样。这样就保证,在传输过程中,如果出现了局部的字节错误,比如增加、丢失、修改了某些字节。将只会影响到有限个字符,并不会导致后续的所有的字符都解析错误。这一点是UTF-16、UTF-32、GB系列都做不到的事情。 第三,同样因为编码后,首字节的前缀与后续字节的前缀都不同,所以从UTF-8字节流中的任一字节开始,往后或者往前都可以很轻易的找到当前字符或者临近字符的起始位置。 第四,依照目前的规则(检查首字节,在第一个0出现之前,有几个1,就代表当前字符需要用多少个字节进行表示),UTF-8可以很轻易地扩展到5个字节、6个字节,甚至是7个字节和8个字节。这就保证了UTF-8可以很轻易地支持Unicode字符集的不断扩充。

与UTF-8和UTF-16相比,UTF-32就比较简单了。

UTF-32的编码规则属于直接映射,并且每个字符都使用四个字节来表示。 因此,UTF-32比UTF-16更浪费空间。但是因为使用的是定长编码(每个字符都是四个字节),所以文本处理速度上要比UTF-8和UTF-16快一些。

在三大UTF编码中,UTF-32既不是最早出现的(UTF-16),也不是最优设计(目前公认UTF-8为最优设计),所以目前已经很少有地方在用了。

上文聊到一个内容,UTF-16编码,有可能使用两个或者四个字节来表示一个字符。那么问题来了,假设存在一个字符,其用UTF-16编码之后,对应的字节流,用16进制表示为0xFA 0xFB。这时候,在计算机存储与传输中,到底应该是0xFA放前面呢,还是应该0xFB放前面呢?

比较遗憾的是,在计算机发展历程中,出于各种各样的原因,大家并没有形成统一,而是出现了多种方案,比较常见的是如下两种: 一、大端序(Big-Endian):又称高尾端序,即数据的尾端存储在内存的高地址;数据的头端存储在内存的低地址。 二、小端序(Little-Endian):又称低尾端序,即数据的尾端存储在内存的低地址;数据的头端存储在内存的高地址。

为了方便理解记忆,这里用几个例子来对大端序和小端序进行下简单的说明。 首先,我们在阅读和书写二进制串时,总是高位在前,低位在后。比如,拿“汉字”为例,其中“汉”对应的unicode编码为“U+6C49”,“字”对应的unicode编码为“U+5B57”,如下所示:

而计算机内存的地址增长,我们设定为从左到右,如下图所示:

那么这种情况下,大端序,就是将写入内存时,字节顺序不变。如下所示:

而小端序,就需要将字节串前后颠倒一下顺序,再写入内存,如下所示:

注意:

***隐藏网址***

此时,在两种字节顺序中的表现如下: 大端序:

小端序:

可以看到,在UTF-16中,即使对于需要使用四个字节来表示的字符,大端序和小端序的作用范围还是被限制到了两个字节。

实际上,这里有一个码元(code unit)的概念。

在解释码元之前,需要先解释另外一个概念:CES。 CES,全称Character Encoding Scheme,可以直译为字符编码模式,是指将字节流转换为最终的bit流的规则。

而上文中,提到过两个相关的概念:CCS(编号字符集)和CEF(字符编码方式)。 CCS(Coded Character Set):编号字符集,指带有数字编号的字符集合。 CEF(Character Encoding Form):字符编码方式,将字符集的数字编号转换为字节流的规则。 三者之间的关系如下:

举个例子(为了方便阅读,最终的bit流以16进制的方式展示):

其中,CEF得出的字节流可以理解为数字编号在计算机中逻辑表示方式,我们前面介绍到的UTF-8、UTF-16都是CEF;而CES的得出bit流序列可以理解为数字编号在计算机中的物理表现方式,上面提到的字节序(大端序、小端序等),就可以认为是字符编码中的CES。

回到码元的概念。码元,可以认为是CEF在将字节流转变为bit流时的最小操作单元。 举个例子,UTF-16中,以2个字节为一个码元,所以在生成bit流时,只会在2个字节内执行大端序和小端序的排序规则。 类似的,在UTF-32中,以4个字节为一个码元。但是,在UTF-8中,以1个字节作为一个码元,所以在使用UTF-8进行编码时,大端序和小端序其实并不会起作用。

由于在使用诸如UTF-16或者UTF-32等以多个字节作为一个码元的编码方式时,对于同一个bit串,使用大端序和小端序解析出来的最终结果很有可能完全不同。所以,在进行数据传输时,数据的生产方必须告知接收方应该使用哪种方式进行解析。而这个告知操作便由BOM(Byte-Order Mark)来实现。

在Unicode中,有一个字符,其编码为U+FEFF,其含义为零宽度不中断空格(ZERO WIDTH NO-BREAK SPACE)。它名义上是个空格,但是宽度为0,所以不可见,也无法被打印出来,换句话说,这个字符其实没啥用。 但是BOM便是借助于这个字符来实现。

为了告知字节流的接收方,这串bit的字节顺序是什么样子的,约定了个办法。就是在每串字节流前面,都要添加一个上述的字符U+FEFF。对于UTF-16如果是大端序,首先读出来的两个字节就会是0xFE 0xFF;如果是小端序,首先读出来的两个字节就会是0xFF 0xFE。这个强行加载字节流最前面,用来表示字节序的字符,就是上文所说的BOM。类似的,对于UTF-32,如果是大端序,首先读出来的就是0x00 0x00 0xFE 0xFF,而如果是小端序,首先读出来的就是0xFF 0xFE 0x00 0x00.

从Unicode 3.2开始,U+FEFF这个字符被规定只能出现在字节流的开头,且只能用于标识字节序,所以这个字符又有了个别名:字节序标记。不过Unicode又添加了个字符用于标识零宽度不中断空格,编码为U+2060。

上文也提到过,对于UTF-8来说,不存在字节序所带来的问题,所以,UTF-8产出的字节流是根本不需要BOM的。不过某些时候,还是会给UTF-8的字节流添加一个BOM注意此时并不是为了标识当前的字节序,而是表示当前字节流是用UTF-8编码完成的(毕竟UTF-8根本没有字节序问题需要BOM解决)。而在UTF-8前面添加的这个BOM,对应的字节流是0xEF 0xBB 0xBF。

对BOM做下简单的整理,如下:

现在,回到文章最初时提的两个问题: Q:为什么同一个字符串,使用GBK和UTF-8进行编码后的字节数不一样? A:因为GBK对于一个字符,恒定使用两个字节来表示,但是UTF-8会使用1~4个字节来表示。而文章开头时,给出的示例字符串为三个汉字“哈哈哈”,在UTF-8中,一个汉字会用三个字节来表示。所以gbk编码后,字节数为2 * 3 = 6,而UTF-8编码后,字节数为3 * 3 = 9. Q:为什么在获取字节数时,不指定charset的结果与指定使用UTF-8时相同? A:可以看一下getByte()的源码,如下:

继续看958行的encode方法:

注意看384行,会取默认的charset,继续跟下去:

看608行,取得时系统属性file.encoding,以此作为默认的编码方式。 验证一下,如下:

***隐藏网址***

最普遍的字符编码是什么

ASCII码。

目前使用最广泛的西文字符集及其编码是 ASCII 字符集和 ASCII 码( ASCII 是 American Standard Code for Information Interchange 的缩写),它同时也被国际标准化组织( International Organization for Standardization, ISO )批准为国际标准。

 ISO2022 标准

规定了在保持与 ISO646 兼容的前提下将 ASCII 字符集扩充为 8 位代码的统一方法。 ISO 陆续制定了一批适用于不同地区的扩充 ASCII 字符集,每种扩充 ASCII 字符集分别可以扩充 128 个字符,这些扩充字符的编码均为高位为 1 的 8 位代码(即十进制数 128~255 ),称为扩展 ASCII 码。

通过了解字符的存储编码,可以解决很多由编码不匹配引起的问题,比如网页乱码、邮件乱码,本文简单扼要地阐明了ASCII编码、EBCDIC编码、GB2312编码、UTF-8编码、以及Base64编码。

字符集和编码的区别.GB2312是一个字符集, 那ANSI是编码, 但是他俩是什么个意思

由权威机构对字符进行编码而形成的编码集合叫做字符集。例如:中国国家标准GB2312就是简体中文字符集;台湾计算机界使用的BIG5码是繁体字中文字符集;日本的JIS X0208标准是日文汉字字符集;韩国的KS C5601是韩国汉字字符集。ANSI(美国国家标准学会)推出了一种双字节编码的标准,将上述三国四方的字符集加以统一,称为 ANSI 编码。在简体中文操作系统中,ANSI 编码代表 GBK 编码;在日文操作系统中,ANSI 编码代表 Shift_JIS 编码。 不同 ANSI 编码之间互不兼容,在国际间信息交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中,没有解决不同字符集的兼容问题。Unicode(万国码、统一码、单一码)则给世界各种语言的每个字符提供了一个唯一的数字,使信息字符能够贯穿多个平台,语言和国家。编码是对每一个具体的字符按规定的方法赋予数字、字母或文字,使之代表特定的信息。

字符集与编码是什么关系

  1. 这个问题其实很简单,你所说的字符集和编码对初学者而言就是一回事。

    人可以直接使用汉字,但计算机只认得0和1的二进制代码。

    编码就是:把汉字跟0和1的二进制代码组合进行一一对应的过程。因为0和1的组合方式非常多,所以你可以编码,别人也可以编,对不对?这就带来了另一个概念↓

    字符集:由权威机构进行编码而形成的编码集合就叫字符集。例如:中文的字符集GB2312就是中国政府自己编出来的;台湾当然不服,所以他们也自己编码(大名鼎鼎的BIG5)

  2. 接下来我再说一下Unicode和ANSI到底是怎么回事?

    字符集的根本就是编码的方法,大家各自的编码方法都不相同,这对电脑的普及和互联造成了非常大的困扰。这时美国老大站出来推出了一种双字节编码的标准叫做:ANSI!中国的GB2312就符合ANSI的标准。

    中国的ANSI是GB2312,日本的ANSI则是JIS;中文的ANSI编码只认中国字,日本的一样只认日本字。所以这种编码标准虽然统一了编码方法,但没有解决不同字符集的兼容问题。

    这时就出现了Unicode编码,一个各种语言通吃的编码。当然这种编码如此强大也是付出了代价的,那就是长度!

  3. 目前默认的字符集和编码是:GB2312和ANSI

  4. 字符集一般都在文件保存时手动指定,或者是软件的默认值一般都会使GB2312,当然部分软件是可以手动指定的。例如:outlook可以在高级选项中手动设置编码。

  5. 编码无法手动添加!现在都用的是windows,他给你什么你就只能用什么。

    你在windows里面添加其他语言支持,就会添加相应语言的字符编码,当然是他给你什么你就用什么,这里无法自定义。

    除非你安装了某些很特殊的软件,例如:IBM深蓝的数控软件,他会安装IBM特殊的字符集到你的电脑上。而这个字符集只能IBM的数据软件能用,其他软件一概不认。

  6. 最后废话:如果想在windows系统上体验各种不同字符集的区别,你需要特殊的软件。记事本、word这种对字符集完全残废的软件是不行的,推荐gvim想学可以尝试下。

unicode是什么

Unicode给每个字符提供了一个唯一的数字, 不论是什么平台, 不论是什么程序, 不论是什么语言。 计算机只是处理数字。它们指定一个数字,来储存字母或其他字符。在创造Unicode之前,有数百种指定这些数字的编码系统。没有一个编码可以包含足够的字符:例如,单单欧州共同体就需要好几种不同的编码来包括所有的语言。即使是单一种语言,例如英语,也没有哪一个编码可以适用于所有的字母,标点符号,和常用的技术符号。

Python2.7 中文字符编码,使用Unicode时,选择什么编码格式

关于编码和乱码的问题,我简单讲一下。

通常问这类问题的人是混淆了若干个不同的概念,并且他们自己也没有意识到自己混淆了这些概念的。

  • 终端显示字符的编码(windows下终端是cmd,linux下是各种terminal,远程登录是putty或者xshell)

  • shell环境的编码。比如中文版windows用的是gbk(向下兼容gb2312),大多数linux发行版使用的是utf-8(LANG=zh_CN.UTF-8)。

  • 文本文件的编码。这个通常取决于你的器,而且有的器支持多种编码的话,你可以在文本开头位置指定器使用特定编码。比如# -*- coding: utf8 -*-,vim看到这行会默认将这个脚本认定为utf-8兼容编码格式。

  • 应用程序的内部编码。一个字符串,作为数据只是一个字节数组,但是作为字符的数组,就有一个解析方式。java和python的内部字符编码是utf-16,python和java都支持用不同的编码来对字节数组进行decode来得到字符数组。

  • 拿题主的问题来解释一下。

    我在ubuntu kylin中文环境下默认terminal中做了同样的实验,但是结果和题主恰好相反:

    看见没有?

  • 题主和我都没有说谎,这是为什么呢?
  • 因为
  • unicode("汉字","gb2312")
  • 这坨代码的含义实际上是:将这里显示的这坨看上去像“汉字”的东西,用gb2312解码,转换为unicode字符串。unicode("汉字","utf-8")类似,只不过是用utf-8解码,转成unicode字符串。(注:这里涉及到两个概念——unicode字符集和utf-8编码——很多时候会用混淆,一个字符集表示一堆符号,而一种编码是用二进制表示这个字符集的一种编码方式。同样是unicode字符集,可以有utf-8、utf-16、utf-32等等编码方式。)

    那这里显示的看上去像“汉字”的,tmd的到底是个什么东西?

  • 如果是在我的环境下,也就是linux utf-8环境下一个utf-8显示终端,能显示成“汉字”的这坨东西,它实际上是以utf-8编码的“汉”字和“字”字两个unicode字符。它们的真实字符值就是u’\u6c49\u5b57’(内码),可以用"汉字".encode("hex")来查看当前终端下(utf-8编码值)的十六进制码。。所以我的命令是,。所以我的命令是,将’e6b189e5ad97’这坨字节数组,转换为unicode的字符数组。——结果毫无难度,没有错误,因为它本来就是utf-8编码,所以能够正常作为unicode字符解码。但是unicode("汉字", "gb2312")就不一样了,这个命令等同于“将’e6b189e5ad97’这坨东西,用gb2312编码方式来解码成字符”,但是实际上由于编码空间并不兼容,使用gb2312编码方式无法解码这么一坨奇葩的数据,所以葛屁了。

  • 在题主的环境下,因为系统终端和默认文件编码都是GBK,所以这个数实际上是这个实际上是gbk(兼容gb2312)的字符“汉字”的真实字节数组。这个实际上是gbk(兼容gb2312)的字符“汉字”的真实字节数组。所以对这坨数据做unicode("汉字","utf8")会失败——因为不管你怎么想,虽然看上去是一样,但是实际上不是同一坨东西啊!

  • 题主现在弄了一个文件,在开始加上了# -*- coding: utf8 -*-这下器看到了,知道这文件是utf-8的了。所以器对读入的一坨坨字节用utf-8来解码,对于输出到磁盘的汉字也用utf-8来编码。所以你在文件里面看到的看上去像“汉字”的东西,就和第一种情况下想同了,当然代码就跑得通。顺便说一下,如果器无视行首这行编码声明,或者器无法支持utf-8格式,那么你弄好的文件在那个器下就会显示乱码,多么简单的道理啊。

  • 所以,要能够正常的显示中文(或者其他什么乱七八糟奇葩的多字节文字),以下条件缺一不可:
  • 终端和环境的编码一致(本机通常是一致的,不一致常常出现在远程登录);如果不一致就需要有器或者文本阅读器做一个兼容两者的转换。

  • 器能够认识文本编码

  • 系统拥有能显示这种字符的字体。

  • 这也就是我为什么一直反对在程序文本中使用除ascii之外的所有编码字符的原因。环境太复杂了,绕开问题远比解决问题轻松。

js 字符编码 ISO-8859-1、UTF-8

如果获取的内容的编码是: ISO-8859-1 ,中文情况下会乱码 如果后端使用URLEncoder编码成: UTF-8

关于字符编码和什么是字符编码的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

什么是字符编码?编码和字符集是什么

本文编辑:admin

本文相关文章:


字符编码简述?什么是字符编码

字符编码简述?什么是字符编码

大家好,关于字符编码很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于字符编码简述的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!本文目录字符编码简述什么是字符编

2024年8月16日 13:35

getparameter中文乱码(java 接收get请求带中文乱码,已经更改字符编码 可是不生效)

getparameter中文乱码(java 接收get请求带中文乱码,已经更改字符编码 可是不生效)

本文目录java 接收get请求带中文乱码,已经更改字符编码 可是不生效request.getparameter()出现中文乱码如何处理get/post提交的中文乱码问题java get方式中文乱码java 接收get请求带中文乱码,已经更

2024年7月24日 05:50

最普遍的字符编码是什么?编码和字符集是什么

最普遍的字符编码是什么?编码和字符集是什么

本文目录最普遍的字符编码是什么编码和字符集是什么字符集与编码是什么关系字符编码简述字符集和编码的区别.GB2312是一个字符集, 那ANSI是编码, 但是他俩是什么个意思什么是字符编码计算机字符编码有哪些在ASCII码字符编码中,什么字符无

2024年6月17日 03:30

ascii编码中(在ASCII码字符编码中,什么字符无法显示或打印出来)

ascii编码中(在ASCII码字符编码中,什么字符无法显示或打印出来)

本文目录在ASCII码字符编码中,什么字符无法显示或打印出来在ASCII编码中,字母A的ASCII编码为41H,那么字母f的ASCII编码为关于c语言asscll码的问题,’8’为何是54、’3’为何是49b在ASCII码字符编码中,什么字

2024年6月5日 06:53

mysql创建数据库字符集(mysql用sql语句创建表和数据库怎么设置字符编码’)

mysql创建数据库字符集(mysql用sql语句创建表和数据库怎么设置字符编码’)

本文目录mysql用sql语句创建表和数据库怎么设置字符编码’如何设置Mysql数据库默认的字符集编码为GBKmysql建表的时候设置表里面的字段的字符集是utf-8要怎么设置默认建好后我去mysql里看字符集都是gbkphp创建mysql

2024年5月23日 16:22

更多文章:


float的形容词(漂浮的词性漂浮的词性是什么)

float的形容词(漂浮的词性漂浮的词性是什么)

大家好,今天小编来为大家解答以下的问题,关于float的形容词,漂浮的词性漂浮的词性是什么这个很多人还不知道,现在让我们一起来看看吧!本文目录漂浮的词性漂浮的词性是什么请问这里的around 和 accidental-like分别是什么词性

2024年7月2日 13:11

jquery实现特效(网页设计高手看过来:这个jquery特效怎么用)

jquery实现特效(网页设计高手看过来:这个jquery特效怎么用)

本文目录网页设计高手看过来:这个jquery特效怎么用怎样用jquery实现弹出框的弹出时渐渐增大,最小化时渐渐变小的特效,在此先感谢!jQuery实现列表内容的动态载入特效jquery的手风琴特效使用JQuery在线制作ppt并在线演示源

2024年7月13日 03:50

核酸检测结果怎么打印成纸质版(核酸检测证明纸质版怎么弄)

核酸检测结果怎么打印成纸质版(核酸检测证明纸质版怎么弄)

本文目录核酸检测证明纸质版怎么弄纸质核酸报告去哪里打印,在哪里打印核酸检测结果核酸检测结果怎么打印,核酸检测如何自己打印核酸检测报告打印流程,核酸证明如何打印核酸检测报告如何打印社区做的核酸检测报告怎么打印如何自己打印核酸检测报告,做完核酸

2024年6月25日 20:21

stripe手续费(为什么说用Qbit趣比汇平台进行独立站收款成本较低)

stripe手续费(为什么说用Qbit趣比汇平台进行独立站收款成本较低)

本文目录为什么说用Qbit趣比汇平台进行独立站收款成本较低跨境收款选Airwallex空中云汇还是stripe跨境收款第三方平台哪个好除了stripe,还有其他的第三方平台推荐吗为什么说用Qbit趣比汇平台进行独立站收款成本较低是的,我那会

2024年7月19日 10:38

coriander(Coriander是什么颜色)

coriander(Coriander是什么颜色)

本篇文章给大家谈谈coriander,以及Coriander是什么颜色对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本文目录Coriander是什

2024年7月11日 08:24

router路由器设置(路由器的设置方法)

router路由器设置(路由器的设置方法)

本文目录路由器的设置方法路由器怎么设置怎么设置路由器wifi设置教程怎么路由器的设置步骤联通3g wifi router路由器怎么设置华硕路由器怎么设置怎么设置路由器呢怎么设置路由器路由器的设置方法1、在手机或电脑的浏览器地址栏输入路由器登

2024年6月10日 03:12

如何快速学好英语(如何简单快速学好英语)

如何快速学好英语(如何简单快速学好英语)

本文目录如何简单快速学好英语怎么快速学好英语怎样才能快速学好英语如何快速学好英语零基础如何快速学好英语如何简单快速学好英语1.每天一词;2.尽可能多地讲英语;3.听外语之声或看外语电视; 4.在单语词典里查找你不认识的词;5.犯了错误立即纠

2024年7月21日 13:27

unity3d教程pdf下载(如何下载 unity3d2017版官方素材)

unity3d教程pdf下载(如何下载 unity3d2017版官方素材)

大家好,如果您还对unity3d教程pdf下载不太了解,没有关系,今天就由本站为大家分享unity3d教程pdf下载的知识,包括如何下载 unity3d2017版官方素材的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!本文

2024年8月30日 11:01

aspen plus安装(win7旗舰版如何安装aspen plus7.2)

aspen plus安装(win7旗舰版如何安装aspen plus7.2)

本文目录win7旗舰版如何安装aspen plus7.2aspen plus 11.1 安装问题aspen plus v7.2 安装过程错误Aspen Plus怎么安装aspenplus 能安装在win11系统上吗aspen plus安装时

2024年7月20日 10:31

spring钢琴多少钱一台(钢琴多少钱一台)

spring钢琴多少钱一台(钢琴多少钱一台)

各位老铁们,大家好,今天由我来为大家分享spring钢琴多少钱一台,以及钢琴多少钱一台的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!本文目录钢琴多少钱一台

2024年8月7日 02:00

汇编指令点亮一个led(汇编语言 单片机 一个开关控制一盏LED的亮灭)

汇编指令点亮一个led(汇编语言 单片机 一个开关控制一盏LED的亮灭)

各位老铁们,大家好,今天由我来为大家分享汇编指令点亮一个led,以及汇编语言 单片机 一个开关控制一盏LED的亮灭的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开

2024年7月24日 15:56

operating(operating怎么读)

operating(operating怎么读)

其实operating的问题并不复杂,但是又很多的朋友都不太了解operating怎么读,因此呢,今天小编就来为大家分享operating的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!本文目录operating怎么读o

2024年8月8日 00:35

directions染发膏(凯维斯果染膏染发梳安全吗可以用吗)

directions染发膏(凯维斯果染膏染发梳安全吗可以用吗)

本文目录凯维斯果染膏染发梳安全吗可以用吗头发染渐变一定要用渐变染发膏吗纯春堂汉斯染发膏怎么用染发膏怎么用如何正确使用染发膏维特丝染发膏vcoo是什么颜色染发剂排名英歌染发膏有害处吗direction染发膏是蜡染吗维特丝染发剂安全吗凯维斯果染

2024年7月23日 18:44

php判断是否为空(PHP中如何判断一个对象是否为空)

php判断是否为空(PHP中如何判断一个对象是否为空)

本文目录PHP中如何判断一个对象是否为空PHP怎样判断一个数组中是否有的键值为空php怎么样判断多个post值是否为空PHP怎么用if语句写一个判断文本框中内容是否为空的语句php如何检测输入框里是否为空php多维数组如何确定是否为空php

2024年5月21日 06:54

password密码是多少(血欲password密码是多少)

password密码是多少(血欲password密码是多少)

其实password密码是多少的问题并不复杂,但是又很多的朋友都不太了解血欲password密码是多少,因此呢,今天小编就来为大家分享password密码是多少的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!本文目录血欲

2024年8月18日 12:40

免费网站转app(在手机上编写了个网页,怎么转成App安装)

免费网站转app(在手机上编写了个网页,怎么转成App安装)

这篇文章给大家聊聊关于免费网站转app,以及在手机上编写了个网页,怎么转成App安装对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。本文目录在手机上编写了个网页,怎么转成App安装靠比较件软件免费下载大全app网站怎么将在自己网站转为

2024年8月24日 22:30

如何做粽子?易买网购物车结算用jsp怎么做

如何做粽子?易买网购物车结算用jsp怎么做

“怎么做”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看如何做粽子?易买网购物车结算用jsp怎么做!本文目录如何做粽子易买网购物车结算用jsp怎么做大学生怎么做兼职挣钱如何做和做什么的区别是什么啊如何做冷饮在计算机原理中,二

2024年7月6日 06:04

textarea换行问题(请教 关于文本框textarea中的换行问题)

textarea换行问题(请教 关于文本框textarea中的换行问题)

本文目录请教 关于文本框textarea中的换行问题如何处理textarea换行关于textarea换行的问题textarea回车换行问题请教 关于文本框textarea中的换行问题《textarea rows=“5“ cols=“40“

2024年7月3日 02:08

前端基础面试题(问下前端行业的同学,现在只会html,css,js,jquery,JS只是懂基础可以在广州找份工作吗)

前端基础面试题(问下前端行业的同学,现在只会html,css,js,jquery,JS只是懂基础可以在广州找份工作吗)

本文目录问下前端行业的同学,现在只会html,css,js,jquery,JS只是懂基础可以在广州找份工作吗Web前端面试题面试技巧有哪些前端面试,面试官问都看过哪些书是要问什么前端转行软件测试,面试应该怎么说即将面试《今日头条》的前端实习

2024年6月27日 02:10

安卓软件开发框架(android 五大应用开发框架是什么)

安卓软件开发框架(android 五大应用开发框架是什么)

本文目录android 五大应用开发框架是什么android开发框架有哪些开发android app有什么架构吗安卓应用开发顶级框架大盘点,有适合你的那一款吗在Android开发过程中搭建一个自己的应用框架有几个步骤android软件开发的

2024年7月9日 02:22

近期文章

本站热文

iphone vpn设置(ios设置vpn快捷开关)
2024-07-22 15:01:12 浏览:2334
windows12正式版下载(操作系统Windows Server 2012 R2,在哪能下载到,公司用的)
2024-07-20 17:26:53 浏览:1730
java安装教程(win10如何安装JAVA)
2024-07-19 19:55:49 浏览:1155
client mfc application未响应(每次进cf就提示client MFC Application未响应该怎么办啊!急急急)
2024-07-20 11:15:58 浏览:1152
标签列表

热门搜索