ISO-8859-1, ASCII, GBK, GB 2312字符集分析

在编程方面经常遇到字符编码的问题,由于对字符集没有一个系统的认识,总是被乱码搞得一头雾水,这篇博文则是对字符编码方面的进行了一下整理,以便日后复习。在学习字符集的过程中,我主要从字符集的(a)编码方式,(b)占用字节,两个方面来进行分析的。

ISO-8859-1/ASCII

参考资料:ISO-8859-1

  ISO-8859-1(Latin1)编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。下图为ISO-8859-1字符集(包括ASCII字符集,图片来自百科)的编码表,编码方式

  在下面代码中,字符串str"úù§ABD"的前三个字符由于不在ASCII编码范围内,故变量asc不能还原为源字符串。由byte数组的长度来看,ISO-8859-1和ASCII为单字节编码。

 1 public static void iso(){
 2     String str = "úù§ABD";
 3     try {
 4         byte[] ch = str.getBytes("ISO-8859-1");
 5         String asc = new String(ch, "ASCII");
 6         String iso = new String(ch, "ISO-8859-1");
 7         System.out.println(str+" length:"+ch.length+" bytecode:"+byte2hex(ch)+"\nASCII:"+asc +"\nISO-8859-1:"+iso);
 8     } catch (UnsupportedEncodingException e) {
 9         // TODO Auto-generated catch block
10         e.printStackTrace();
11     }
12 }

  OUTPUT:

úù§ABD length:6 bytecode: fa f9 a7 41 42 44
ASCII:???ABD
ISO-8859-1:úù§ABD

GBK/GB2312

参考资料:GB 2312GBK

  GB 2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;同时,GB 2312收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。GB 2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。对于人名、古汉语等方面出现的罕用字,GB 2312不能处理,这导致了后来GBK及GB 18030汉字字符集的出现。

  

  汉字区位码:GB 2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。每个汉字可以使用一个4位的十进制表示,称为区位码,前两位为区码,后两位为位码。

  01-09区为特殊符号。

  16-55区为一级汉字,按拼音排序。

  56-87区为二级汉字,按部首/笔画排序。

  10-15区及88-94区则未有编码。

  举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。

  字节编码方式:

  在使用GB2312的程序中,通常采用EUC储存方法(分别将区码和位码加上0xA0),以便兼容于ASCII。

  每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。

  “高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上 0xA0)。 由于一级汉字从16区起始,汉字区的“高位字节”的范围是0xB0-0xF7,“低位字节”的范围是0xA1-0xFE,占用的码位是 72*94=6768(72个汉字分区)。其中有5个空位是D7FA-D7FE。

  例如“啊”字在大多数程序中,会以两个字节,0xB0(第一个字节) 0xA1(第二个字节)储存。

  GBK全称《汉字内码扩展规范》,GBK编码,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。

 1 public static void gb(){
 2     String str = "啊aA";
 3     byte[] ch;
 4     try {
 5         ch = str.getBytes("GB2312");
 6         System.out.println("ch length:"+ch.length+" bytecode:"+byte2hex(ch));
 7         ch = str.getBytes("GBK");
 8         System.out.println("ch length:"+ch.length+" bytecode:"+byte2hex(ch));
 9     } catch (UnsupportedEncodingException e) {
10         // TODO Auto-generated catch block
11             e.printStackTrace();
12     }
13 }

  OUTPUT:

ch length:4 bytecode: b0 a1 61 41
ch length:4 bytecode: b0 a1 61 41

  从程序可以看出GB2312,GBK是不定长的,汉字为2个字节,英文字符为一个字节。由于表示汉字或图形符号的“高位字节”的首个bit都为1,而ASCII首个bit为0,而实现了这两种字符集对ASCII的兼容。

UTF-8/unicode

时间: 2024-10-17 18:28:25

ISO-8859-1, ASCII, GBK, GB 2312字符集分析的相关文章

Native2asciiUtil 文本文件转UNICODE编码文件(支持UTF-8,Unicode,UTF-16BE,ANSI|ASCII,GBK)

package com.ctl.util; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * * @author Administrator * @Description \u5C06\u6587\u672C\u6587\u4EF6\u8F6C\

解决mysql中表字符集gbk,列字符集Latin1,python查询乱码问题

最近在公司碰到一个异常蛋疼的情况,mysql数据库中,数据库和表的字符集都是'gbk',但是列的字符集却是'latin1',于是蛋疼的事情出现了. 无论我连接字符串的`charset`设置为`gbk`,`utf8`,`latin1`中的任意一种,查询出来的表中数据的中文都是乱码,在查询中加上如下代码也还是无济于事: SET NAMES latin1 在更换各种py链接库,然后疯狂的google和问了各路大神之后,终于找到解决思路如下: 1.通过hex(column)将列中的数据2进制转为16进制

python字符集分析,解决windows下FTPClient下载中文名称文件乱码

python中的中文编码一直以来都是一个极为头大的问题,经常抛出编码转换的异常,python中的str和unicode到底是一个什么东西呢?在python中提到unicode,一般指的是unicode对象,例如'哈哈'的unicode对象为u'\u54c8\u54c8',而str,是一个字节数组,这个字节数组表示的是对unicode对象编码(可以是utf-8.gbk.cp936.GB2312)后的存储的格式.这里它仅仅是一个字节流,没有其它的含义,如果你想使这个字节流显示的内容有意义,就必须用正

Linux课题实践三——字符集总结与分析

Linux课题实践三——字符集总结与分析 20135318  刘浩晨 字符是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等.字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII字符集.GB2312字符集.BIG5字符集. GB18030字符集.Unicode字符集等. 1.总结ISO.UCS/UTF.GB系列字符集的由来.异同 (1).ISO/IEC ISO/IEC 646:是国际标准化组织(ISO)及国际电工委员会(IEC)联合制定

转:字符集和字符编码学习笔记

原文来自于:http://www.king-liu.net/146/ 在web开发中我们总会遇到这样那样的字符编码问题,例如,当我们在代码编辑器里可以好好显示的html文档在浏览器里却变成了乱码,有时候为了能让我们的页面正常显示我们可能要忙上一天都无法解决(我可是深有体会).为了搞清楚字符编码的问题,今天我也花了很长时间去百度.这里我和大家分享一下我的感想,不对之处,欢迎指正. 首先要了解下什么是字符编码和字符集. 字符集(Charset):是一个系统支持的所有抽象字符的集合.字符是各种文字和符

Python字符编码很难吗?今天一文带你深入!从此不再疑惑!

不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError.UnicodeDecodeError 错误,每当遇到错误我们就拿着 encode.decode 函数翻来覆去的转换,有时试着试着问题就解决了,有时候怎么试都没辙,只有借用 Google 大神帮忙,但似乎很少去关心问题的本质是什么,下次遇到类似的问题重蹈覆辙,那么你有没有想过一次性彻底把 Python 字符编码给搞懂呢? 完全理解字符编码 与 Python 的渊源前,我们有

Python-3 文件和字符编码

文件 打开文件模式 ''' "r"只读模式(默认). w,只写模式,不可读,不存在则创建:存在则删除内容 a,追加模式,可读,不存在则创建:存在则只追加内容 x, 写模式,当文件系统上不存在,才可以写.也就是不允许覆盖已存在的文件内容 "+"表示可以同时读写某个文件: r+,可读写文件.可读:可写:可追加 w+,写读 a+,同a "U"表示在读取时,可以将 \r \n \r\n自动转换成\n(与r或r+ 模式同使用): rU r+U "

python --- 字符编码学习小结

上半年的KPI,是用python做一个测试桩系统,现在系统框架基本也差不多定下来了.里面有用到新学的工厂设计模式以及以及常用的大牛写框架的业务逻辑和python小技巧.发现之前自己写的代码还是面向过程思想的多,基本没有面向对象的思想,近半年看的代码给了很大的触动,我需要升级我的技能了,于是也花了挺多时间在这个KPI学习上,现在先总结下在做这个系统时我所面临到的python的字符编码问题. 字符编码问题,如果处理有问题,可能直接就报错了:如果处理不得当,中文就会显示乱码.这是最初接触字符编码遇到问

字符编码常识

基本常识: 1.位和字节 位:(bit),计算机里存放的二进制的值(0/1). 字节:(byte),一个字节由8位组成.8个位的组合有256个组合方式,其值范围:“00000000-11111111”,常用16进制来表示. 通常所说的字符编码,就是指定义一套规则,将真实世界里的字母.字符与计算机二进制序列进行相互转化. 2.编码标准 (1) 拉丁编码(适用于美国,欧洲) <1> ASCII编码 只支持基础拉丁字母.设计:用1个字节来表示1个字符.且最高位为0,表示字符含义的只有7位,所以可表达