关于编码格式的总结
来源:互联网 发布:nginx lua redis 安装 编辑:程序博客网 时间:2024/05/17 01:23
最近在用Java做文本处理的时候,经常遇到一些乱码的问题,因此决定好好看一下编码格式的问题。所谓编码,从我的理解就是一种映射关系,即数字到符号的一一映射;而编码标准就是那张映射表,它决定了哪一个数字对应了哪一个符号,在计算机的世界里面实际是只有数字的,但是标准的存在则是数字与符号联系的纽带。现在常用的编码主要有以下几种:ASCII、Unicode、UTF-8(有无BOM)、UTF-16、UTF-32、GBK等。
ASCII
ASCII是指美国标准信息交换代码,是基于拉丁字母的一套电脑编码系统,是现今最通用的单字节编码系统。ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符,而我们常用的其实是使用指定7位二进制数组合来表示128种字符的标准ASCII。
在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。后128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。
对于英语来说,标准ASCII几乎涵盖了所有的字符,因而对于只使用英文字符和数字的情况,采用ASCII编码就完全足够。但对于其他语言,128字符是完全不够的,比如常用的中文汉子就有几千个,更不提全世界所有的语言字符加起来的和,所以一种通用的编码方式就产生了。
Unicode
Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode用0~0x10FFFF(使用21位二进制数即可表示完全)来映射这些字符,最多可容纳1114112个字符(17*65536,17表示0~0x10共17个数字)。
通用字符集(Universal Character Set, UCS)是由ISO制定的ISO 10646标准所定义的标准字符集。UCS-2用两个字节编码,UCS-4用4个字节编码。UCS-4根据最高位为0的最高字节分成2^7=128个group,每个group再根据次高字节分为256个平面(plane),Unicode计划使用了17个平面,一共有17×65536=1114112个码位。group 0的平面0被称作BMP(Basic Multilingual Plane)。如果UCS-4的前两个字节为全零,那么将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。所以其实UCS-2只能表示Unicode中在0~0xFFFF内的字符,其中中文的范围为4E00~9FBF,共定义了27973个汉字。除此之外,平面2上还定义了43253个汉字。
Java中基本数据类型char采用的就是Unicode编码,确切说应该是UCS-2,即使用两个字节来表示一个字符,所以Java中char类型能表示的字符范围为0~0xFFFF,超过这个范围的Unicode编码实际上char是表示不了的,即char只能表示Unicode的BMP平面的字符。
UTF-8
UTF-8以字节为单位对Unicode进行编码,其特点是对不同范围的字符使用不同长度(1~6字节)的编码。对于0x00~0x7F之间的字符,UTF-8编码与标准的ASCII编码完全相同,即向下兼容标准ASCII编码。如果文本中全是英文字符,那么采用ASCII编码读写与采用UTF-8编码读写都是可以的。其具体编码方式如下:
我们常常也会看到UTF-8带BOM,这里的BOM其实是用来区分字节序的。字节序有两种,分别为“大端”(Big Endian,BE)和“小端”(Little Endian,LE)。对于BE,内存在载入数据时先将高序字节存储在起始地址,再存入低序字节,而LE恰恰相反。Unicode标准建议传输字节流前,先传输被作为BOM的字符来判别该字节流采用的是哪种编码方式,这些字符在Unicode中都是未定义的码位,不应该出现在实际传输的内容中。
UTF-8其实不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM,不含 BOM 的 UTF-8 才是标准形式。在 UTF-8 文件中放置 BOM 主要是微软的习惯,微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。如果我们接收到以EF BB BF开头的字节流,就知道这是采用的UTF-8编码了。无BOM的UTF-8使用的其实更广,所以一般情况下尽量用无BOM的形式。
UTF-16
UTF-16编码以16位无符号整数为单位。我们把Unicode编码记作U。编码规则如下:如果U<0x10000,U的UTF-16编码就是U对应的16位无符号整数(两个字节);如果U≥0x10000,我们先计算U’=U-0x10000,然后将U’写成二进制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx(四个字节)。
为了将两字节的UTF-16编码与四字节的UTF-16编码区分开来,Unicode编码的设计者将0xD800-0xDFFF保留下来,并称为代理区(Surrogate)。计算机读取两个字节的数据后,发现如果这两个字节在0xDB00~0xDBFF,那么这个字符必定采用的是四字节进行编码,其后两个字节的范围必定在0xDC00~0xDFFF之间。如果我们处理的文本没有在0xDB00~0xDBFF范围内的字符,那么采用UTF-16编码与采用UCS-2编码是没有区别的(不考虑BOM,只考虑数值)。Java中的String采用的就是UTF-16编码。
UTF-32
UTF-32编码以32位无符号整数为单位。Unicode的UTF-32编码就是其对应的32位无符号整数,与UCS-4一致。
GBK
GBK全称《汉字内码扩展规范》(GBK即“国标”、“扩展”汉语拼音的第一个字母,英文名称:Chinese Internal Code Specification),完全局限于汉字编码 。GBK编码,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1(即UCS)和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。
- 关于编码格式的总结
- 关于NSKeyedArchiver的编码格式
- 关于QT的编码格式
- SMTP-关于邮件编码的格式
- 关于手游的文件编码格式
- 关于文本编码格式转换的问题
- 关于文件编码格式的一点探讨
- 关于编码格式的浅谈【经验】
- 关于格式控制的总结
- 关于编码的一些总结
- 关于字符编码格式
- 关于编码格式
- 文本编码格式总结
- JAVASE总结--编码格式
- Qt编码格式总结
- 关于printf输出格式类型的总结
- 关于编码问题的若干总结
- 关于AFNetWorking编码格式问题
- 获取指定content中第一张图片路径
- uva 11889
- 海量数据处理面试题集锦
- viewPager+fragment取消预加载+及每次加载都要求请求
- git创建与使用步骤
- 关于编码格式的总结
- 格蕾丝·赫柏
- 【沙龙干货分享】你要知道的N个Android适配问题
- attr陷阱
- bit-map 详解
- access 小结
- C#比较程序版本号的方法
- PDO的错误处理模式
- The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar