同步操作将从 Bruce/字符集和字符编码 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
计算机中储存的信息都是用二进制数表示的;按照何种规则将字符存储在计算机中,如'a'用什么表示,称为"编码";反之,将存储在计算机中的二进制数解析显示出来,称为"解码";
字符集(Charset):是一个系统支持的所有抽象字符的集合;字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等;
字符编码(Charset):是一套映射规则,根据这个映射规则可以将某个字符映射成二进制形式的数据以便在计算机中存储和传输;
常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字;
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以勉强显示其他西欧语言,它是现今最通用的单字节编码系统;
ASCII字符集:主要包括控制字符(回车键、退格、换行键等);可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
ASCII编码:将ASCII字符集转换为计算机可以接受的数字系统的数的规则。使用7位(bits)表示一个字符,共128字符;但是7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符(EASCII),共256字符。ASCII字符集映射到数字编码规则如下图所示:
为了显示中文,必须设计一套编码规则用于将汉字转换为计算机可以接受的数据,GB2312规定:
1.一个小于127的字符的意义与原来相同;
2.两个大于127的字符连在一起时,就表示一个汉字;
GB2312还把数学符号、罗马希腊的 字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了;
GB2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆绝大多数使用场景;对于罕用字,GB2312不能处理,这导致了后来GBK及GB 18030汉字字符集的出现;
由于GB 2312-80只收录6763个汉字,很多汉字并未有收录在内,于是厂商微软利用GB 2312-80未使用的编码空间,收录GB 13000.1-93全部字符制定了GBK编码,根据微软资料,GBK是对GB2312-80的扩展;如下图所示:
字符集&字符编码 | 低字节 | 高字节 |
---|---|---|
GB2312 | 0xB0-0xF7(176-247) | 0xA0-0xFE(160-254) |
GBK | 0x81-0xFE(129-255) | 0x40-0xFE(64-254) |
GB 18030,全称:国家标准GB 18030-2005《信息技术 中文编码字符集》,与GB 2312-1980完全兼容,与GBK基本兼容,支持GB 13000及Unicode的全部统一汉字,共收录汉字70244个,GB 18030主要有以下特点:
1.与UTF-8相同,采用多字节编码,每个字可以由1个、2个或4个字节组成
2.编码空间庞大,最多可定义161万个字符
3.支持中国国内少数民族的文字,不需要动用造字区
4.汉字收录范围包含繁体汉字以及日韩汉字
当计算机传到世界各个地区时,为了适合当地语言和字符,都会设计和实现类似GBXXXX的编码方案,以适应本地化应用和发展;例如中国台湾地区使用繁体中文,就本地化设计和实现了BIG5字符集&字符编码,日本的JIS字符集&字符编码,GBXXXX,BIG5,JIS等统称现在统一称为 MBCS,MBCS兼容ASCII,其缺点也比较明各个国家地区自定义的字符集&字符编码无法相互兼容;
Windows系统将这些互不兼容的字符集&字符编码统称为ANSI,在Windows下编辑TXT另存为时编码选择ANSI时,使用的编码就是,根据系统给的区域语言来决定的,中国大陆就是GBK,中国台湾就是BIG5等等,如下图所示:
注1:DOS下使用chcp命令可以查看系统使用的代码页的编号
注2:Windows10及其以上版本提供了[使用Unicode UTF-8提供全球语言支持(U)] 此时TXT另存为时编码选择ANSI或VS里的多字节字符集都指UTF8编码
为了解决MBCS兼容性问题,一个伟大的创想产生了Unicode,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求,Unicode的范围为0x0~0x10FFFF,一共包含1114112个码位,整个编码空间划分为17个平面(plane),每个平面包含65536个码位,其中0号空间叫做基本多文种平面,其他平面叫做补充平面;
Plane | 范围 | 名称 |
---|---|---|
Plane 0 | U+0000 ~ U+FFFF | 基本多文种平面(Basic Multilingual Plane, BMP) |
Plane 1 | U+10000 ~ U+1FFFF | 多文种补充平面(Supplementary Multilingual Plane, SMP) |
Plane 2 | U+20000 ~ U+2FFFF | 表意文字补充平面(Supplementary Ideographic Plane, SIP) |
Plane 3 | U+30000 ~ U+3FFFF | 表意文字第三平面(Tertiary Ideographic Plane, TIP) |
Plane 4 ~ 13 | U+40000 ~ U+4FFFF | 未使用(unassigned) |
Plane 14 | U+E0000 ~ U+EFFFF | 特别用途补充平面(Supplementary Special-purpose Plane, SSP) |
Plane 15 ~ 16 | U+F0000 ~ U+10FFFF | 保留作为私人使用区(Private Use Area, PUA) |
Unicode是为整合全世界的所有语言文字而诞生的。任何文字在Unicode中都对应一个值,这个值称为代码点(码位),代码点的值通常写成 U+ABCD 的格式,而文字和代码点之间的对应关系就是UCS-2(Universal Character Set coded in 2 octets),UCS-2是用两个字节来表示代码点,其取值范围为 U+0000~U+FFFF,U+D800..U+DFFF的值不对应于任何字符,为代理区;
为了能表示更多的文字,人们又提出了UCS-4,即用四个字节表示代码点,它的范围为 U+00000000~U+7FFFFFFF;
在介绍UTFXX之前让我们先了解下UTF的由来,Unicode的实现方式称为Unicode转换格式,Unicode Transformation Format,简称为UTF;
使用4字节的数字来表达每个字母、符号,或者表意文字(ideograph),每个数字代表唯一的至少在某种语言中使用的符号的编码方案,称为UTF-32,UTF-32又称UCS-4是一种将Unicode字符集的编码实现,对每个字符都使用4字节,效率较低;
ISO10646 标准定义了UCS-4的31位编码形式,其中通用字符集UCS中的每个编码字符都由 0 到十六进制之间的整数的代码空间中的 32 位友好代码值表示7FFFFFFFF,因为实际上只有 17 个平面在使用,所以当前所有的代码点都在0到0x10FFFF之间。UTF-32 是仅使用此范围的 UCS-4 的子集,后来Unicode修订所有未来的字符分配都将被限制在 BMP 或前 14 个补充平面,因此 UTF-32 将能够表示所有 Unicode 字符,UCS-4 和 UTF-32 现在是相同的;
Unicode字符集包含字符非常多,但是实际上大多数人不会用到超过前65535个以外的字符,因此有了另外一种Unicode编码方式,叫做UTF-16(因为16位 = 2字节),UTF-16范围UTF-16将0–65535范围内的字符编码成2个字节,如果真的需要表达那些超过这65535范围的Unicode字符,则需要使用一些技巧来实现,UTF-16编码最明显的优点是它在空间效率上比UTF-32高两倍,因为每个字符只需要2个字节来存储;UNICODE补充平面的字符位共有2^20个,也就是说,对应这些字符至少需要20个二进制位,UTF-16将这20位拆成两半,前10位映射在代理区U+D800到U+DBFF(空间大小2^10),后10位映射在代理区U+DC00到U+DFFF(空间大小2^10),UNICDOE码位转UTF-16编码方式如下:
1.从U+0000至U+D7FF以及从U+E000至U+FFFF的码位对应UnicodeBMP平面,包含了最常用的字符;
2.从U+D800到U+DFFF的值不对应于任何字符,为代理区;
3.从U+10000到U+10FFFF的码位,补充平面中的码位,在UTF-16中被编码为一对16比特长的码元(4字节),称作代理对;
3.1 码位减去0x10000, 得到的值的范围为20比特长的0..0xFFFFF(因为Unicode的最大码位是0x10FFFF,减去0x10000后,可以用20个二进制位表示;
3.2 高位的10比特的值被加上0xD800得到第一个码元或称作前导代理, 值的范围是0xD800..0xDBFF;
3.3 低位的10比特的值被加上0xDC00得到第二个码元或称作后尾代理, 现在值的范围是0xDC00..0xDFFF;
示例
字符 | UNICODE码位 | UTF-16BE | UTF-16LE |
---|---|---|---|
a | 0x00000061 | 0xFEFF0061 | 0xFFFE6100 |
我 | 0x00006211 | 0xFEFF6211 | 0xFFFE1162 |
😊 | 0x0001F60A | 0xFEFFD83DDE0A | 0xFFFE3DD80ADE |
将BMP平面的字符 😊 的UTF-8编码,转换为UNICODE字符集的UCS-4标准的代码点过程:
UCS-2是一种固定宽度编码,每个字符使用两个字节;也就是说,它最多可以代表2^16个字符或略多于65535个字符,而UTF-16是一种可变宽度编码方案,每个字符最少使用2个字节,最多使用4个字节,这使得UTF-16可以用Unicode表示任何字符,对于基本多语言平面的65535个字符,UCS-2和UTF-16具有相同的代码点;所以它们基本上是等价的,这使具有UTF-16功能的应用程序能够正确解释UCS-2代码;
BOM(ByteOrderMark)
为了识别 Unicode 文件,Unicode 定义了 ZERO WIDTH NOBREAK SPACE(U+FEFF),作为一个 字节顺序标记(Byte Order Mark) 来识别文件中使用的编码和字节顺序,Linux/UNIX 并没有使用 BOM,因为它会破坏现有的 ASCII 文件的语法约定,对于UTF-16,字节顺序标记是U+FEFF,如果收到一个以字节FF FE开头的UTF-16编码的文档则是小端序,如果它以FE FF开头则是大端序;
如果你使用过VS系列的IDE,对于以下配置一定不陌生,如下图所示:
这里的VS配置Unicode字符集或文件另存为的编码Unicode均指使用UTF-16编码的Unicode字符集,这让很多Win开发者在学习初期都认为Unicode就是UTF-16;
UTF-16应用十分广泛,.Net,JAVA都是使用UTF-16来编码所有字符和字符串的;
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码(定长码),也是一种前缀码,它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用,因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码;
UTF-8使用一至四个字节为每个字符编码:
1.128个US-ASCII字符只需一个字节编码(Unicode范围由.U+0000至U+007F);
2.带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要二个字节编码(Unicode范围由U+0080至U+07FF);
3.其他基本多文种平面(BMP)中的字符(这包含了大部分常用字)使用三个字节编码;
4.其他极少使用的Unicode辅助平面的字符使用四字节编码;
编码方式:
1、如果只有一个字节,那么最高的比特位为 0,这样可以兼容 ASCII;
2、如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头;
二进制示例:
0xxxxxxx:单字节编码形式,这和 ASCII 编码完全一样,因此 UTF-8 是兼容 ASCII 的;
110xxxxx 10xxxxxx:双字节编码形式(第一个字节有两个连续的 1);
1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式(第一个字节有三个连续的 1);
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式(第一个字节有四个连续的 1);
UTF8-UNICODE码位对照表如下所示:
示例
字符 | UNICODE码位 | UTF-8 |
---|---|---|
a | 0x00000061 | 0x61 |
我 | 0x00006211 | 0xE68891 |
😊 | 0x0001F60A | 0xF09F988A |
将BMP平面的字符 我 的UTF-8编码,转换为UNICODE字符集的UCS-4标准的代码点过程:
在处理经常会用到的ASCII字符方面非常有效,在处理扩展的拉丁字符集方面也不比UTF-16差,对于中文字符来说,比UTF-32要好,由位操作的天性使然,使用UTF-8不再存在字节顺序的问题了,一份以utf-8编码的文档在不同的计算机之间是一样的比特流;UTF-8是ASCII的一个超集,因为一个纯ASCII字符串也是一个合法的UTF-8字符串,所以现存的ASCII文本不需要转换;
1.DaoNet,JAVA内部为什么用UTF-16来编码字符和字符串,仅仅是因为历史原因吗?
2.UTF-16和UTF-8分别更适用那些场景?
3.上面提到UTF-8不存在字节序的问题,那什么是有UTF8-BOM(0xEFBBBF)格式呢?
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。