1字符集 iso latin_技术分享|字符集和编码规则在开发中的实际运用

90a02aa7204ef75e2b20dc6d4c0a68cc.png 03108e53689db832ea8f69959676cdf8.png

陈志力

合肥科技研发中心

在计算机内部,各种信息都是0和1的不同排列,连续不断的0和1如何表达各式各样的信息呢,这就要从字符集和编码规则开始说起。

一、字符集

简而言之,字符集就是一些字符的集合,不同国家和地区用的文字不同,相应的也就有不同的字符集。常见的字符集有ASCII字符集、扩展ASCII字符集、GB2312字符集、GBK字符集、GB18030字符集、BIG5字符集、JIS字符集、Unicode字符集等等。

二、字符集和编码规则的关系

编码规则是描述字符集的各种字符如何对应到二进制编码的规则。

三、编码规则的种类

(1)标准ASCII编码:最开始,计算机在美国使用,这时诞生了ASCII字符集,用8位二进制数表示,总共有256种状态,从第0到第127的状态编码分别表示控制码、空格、标点、数字和字母等符号。

(2)扩展ASCII编码:随着计算机使用范围扩大,第128到第255的空位也开始使用,除了新的字母和符号,一些横线、竖线和交叉等形状也编码进来,序号一直编到第255个状态,这是扩展ASCII编码。

(3)IOS-8859编码:windows进入欧洲时,诞生了新的编码方案IOS-8859系列编码。其中的ANSI/ISO-8859-1-1987,简称ISO-8859-1,编码全称叫做「American National Standard for Information Processing-8-Bit Single-Byte Coded Graphic Character Sets-Part 1: Latin Alphabet No 1」,简写作Latin-1。欧洲的不同地方有不同的编码,比如西欧字符编码ISO-8859-1、东欧字符编码ISO-8859-2等等。

(4)GB2312编码:中国开始使用计算机后,8位编码已用完,为了给汉字编码,编码位扩展到两字节16位,规定两个大于127的单字节编码连在一起表示汉字,同时数学符号、罗马希腊字母、日文假名也都编了进去。ASCII编码里原有的数字、标点、字母也重新赋予了两字节的编码,这就是常说的“全角”字符;而原来在127号以下的叫做“半角”字符。GB2312采用单双字节变长编码,英文使用单字节编码,完全兼容ASCII字符编码,中文部分采用双字节编码。

(5)GBK编码:随着计算机在中国的运用,中国的文字又很多,于是不再要求两个字节都是127号之后的编码,只要第一个字节大于127就表示一个字符的开始,这样进一步扩大了编码容量,并向下兼容GB2312编码。

(6)GB18030编码:GB18030有两个版本,GB 18030-2000和GB 18030-2005。GB18030-2000是GBK的取代版本,它在GBK的基础上增加了中日韩统一汉字扩展A区;GB18030-2005是在GB18030-2000的基础上增加了中日韩统一汉字扩展B区。GB18030采用变长多字节编码,每个字可由1个、2个或4个字节组成,编码空间庞大,最多可定义161万个字符。

(7)BIG5字符集编码、

SHIFT_JIS字符集编码:这两个编码和GBK类似,仅编码代表的字符集不同,BIG5是中国台湾、香港地区使用的繁体字符集编码;SHIFT_JIS是日本使用的日文字符集编码。

(8)Unicode字符编码:为解决不同字符集之间的乱码问题,国际组织制定了可以容纳世界上所有文字和符号的字符编码方案,对所有语言进行统一编码。为了兼顾存储和容量,Unicode采用变长编码方式,根据编码规则不同,分为UTF-8、UTF-16、UTF-32三种。

① UTF-8编码,基本单位为1字节,每次扩展增加1个字节,即使用1、2、3、4字节编码。UTF-8对单字节字符友好,如果一个字节最高位是0,则该字节代表1字节字符,此时UTF-8等同于ASCII;当表示双字节字符时,这两个字节分别是0b110xxxxx和0b10xxxxxx形式,共有11个可编码比特位,容量为2048;当表示三字节字符时,三个字节分别是0b1110xxxx和两个0b10xxxxxx,共16个可编码比特位,容量为65536;其他情况不再赘述。从以上可以看出,UTF-8需要三个字节才能达到双字节字完整容量,因此存储诸如中文、日文、韩文等字符时需要更多字节,但在存储英文时只需1个字节。目前互联网上英文网页占多数,所以网页绝大多数使用的是UTF-8编码。

下表总结了UTF-8编码规则,字母x表示可用编码位:

b96465bc431cd560430db3a8c5b2e94b.png

根据上图,解读UTF-8编码非常简单。如果一个字节的第一位是0,则这个字节单独代表一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少字节。

② UTF-16编码,基本单位为2字节,每次扩展增加2个字节,即使用2、4字节编码;相较于UTF-8,只要两个字节就可以提供65536的容量,在存储中文、日文、韩文时往往需求更少的空间,不过在存储英文时同样需要两字节的空间。

③ UTF-32编码,基本单位为4字节,即每个字符都使用4个字节编码。虽然定长4字节看似方便,但占用空间较大,存储和传输成本高,而且方便性上并没有超出太多,所以应用并不广泛。

需要注意的是,Unicode编码方式在文件开头都有BOM标志块,用来表明当前文本使用何种类型的Unicode编码方式。UTF-8文档的BOM是0xEF,0xBB和0xBF;UTF-16文档的BOM根据大端序或者小端序的不同而有所区别,小端序时BOM为0xFF和0xFE,代表接下来出现的两两一组的字节中先出现的第一个字节应放入内存高地址,大端序时BOM为0xFE和0xFF,代表先出现第一个字节应放入内存低地址。

以数字0x1234为例,从左到右,左边0x12为高字节,0x34为低字节,小端序时数据在内存存储形式为a:0x34,a+1:0x12(a为内存低地址、a+1为内存高地址);大端序时数据在内存中存储为a:0x12,a+1:0x34(a为内存低地址、b为内存高地址)。

目前Windows和Linux大多使用小端序,而Mac使用大端序,根据大端小端的不同,BOM共有五种类型,如下图:

c5f91c1e0f77f061e898775afe5e2bb0.png

四、字符集和编码规则在开发中的实际运用

在开发过程中会经常遇到有关字符集和编码规则的问题,下面列出一些常见情况:

1. 数据库字符编码和表字段存储长度设计问题

应考虑应用系统特点,为数据库选择合适的字符集编码,例如,存储内容大多是英文时,则应设置为UTF-8,大多数是中文等双字节字符时,则应设置为GBK为好。

对于字段长度,从性能和存储容量上考虑,以varchar2为例,要明确定义varchar2字段长度,避免使用默认最大长度,并且只设置需要的长度,在处理加工数据时也要考虑不同编码规则下字节占用的不同,防止出现字段过长无法存储的情况。

2. JSP 文件中的编码设置

一般JSP文件中有三个设置编码的地方:pageEncoding、contentType的charset和Meta的charset,如下图:

1262443b1cf4bfe89532d8f635d6e320.png

PageEncoding是JSP文件本身的编码,不设置时默认为IOS-8859-1。

ContentType的charset是指服务器发送给客户端时的内容编码,Meta里的charset和ContentType中charset效果一样,但ContentType中指定的charset优先生效。

3. Http请求、Http响应字符集问题

使用request.setCharacterEncoding()设置HTTP请求编码,指定后可以通过getParameter()直接获得正确的字符串,如果不指定,则默认使用iso8859-1编码,该指定只对POST方法有效,对GET方法无效。

使用response.setContentType()、response.setCharacterEncoding()指定 HTTP 响应编码, response.setContentType设置后可通过setCharacterEncoding覆盖设置。

setContentType还可以设置发送到客户端的响应的内容类型等。

4. GET 请求中的编码

GET请求中的PathInfo和QueryString部分,在不同浏览器和设置下编码规则不同,一般地,建议不要在GET请求中使用中文字符,如果必须要使用,应先用encodeURIComponent()方法对中文字符编码,然后再发送GET请求。

5. JVM 默认字符集

不主动配置-Dfile.encoding的情况下,默认是操作系统的编码,配置 JVM 启动参数-Dfile.encoding,可以更改JVM 默认字符集编码。

6. Java的I/O 流与字符集

Java 的 I/O 流,分为“字节流”与“字符流”,字节流有FileInputStream、FileOutputStream等,字符流有FileReader、FileWriter等,以Stream结尾的为字节流,以Reader或Writer结尾的是字符流。

字符流与字节流转换时,要注意编码问题,字节流按字节读取或写入,不涉及编码问题,字符流使用时需要指定正确的编码,具体转换方法如下图:

696d42f373a145f60fd9d3237f5e4ac2.png

字符集和编码问题在日常开发中经常遇到,深入掌握其中原理,具体情况具体分析,才能迅速高效的解决问题。

aa890bb263e70e286342d0e91946f564.gif ec78fc627b5b0b9415c4d6e6b9609122.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值