常见字符编码

>ASCII

在所有字符集中,最知名的可能要数被称为ASCII的7位字符集了。它是美国标准信息交换代码(American Standard Code for Information Interchange)的缩写, 为美国英语通信所设计。它由128个字符组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(退格、响铃等)组成。

>iso-8859-1(不支持中文)

由于ASCII是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问题。因此,创建出了一些包括255个字符的由ASCII扩展的字符集。有一种8位字符集是ISO 8859-1Latin 1,也简称为ISO Latin-1。它把位于128-255之间的字符用于拉丁字母表中特殊语言字符的编码,也因此而得名。

>gb2312、gbk、gb1830(系统默认编码,中国的国标码)

GB2312是一个简体中文字符集的中国国家标准,全称为《信息交换用汉字编码字符集•基本集》,又称为GB0,由中国国家标准总局发布,1981年5月1日实施。GB2312编码通行于中国大陆;新加坡等地也采用此编码。

GB2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;同时,GB 2312收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。

对于人名、古汉语等方面出现的罕用字,GB2312不能完全包括,这导致了后来GBK及GB18030汉字字符集的出现。

GB2312兼容ASCII码,这部分还是每个字符占1个字节。每个汉字字符占2个字节。GB2312是中国自己的字符集,而其他国家也都有自己的字符集!!!

>Unicode

Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的编码,以满足跨语言、跨平台进行文本转换、处理的要求。它通过增加一个高字节(2个字节)对ISO Latin-1字符集进行扩展,当这些高字节位为0时,低字节就是ISO Latin-1字符。UNICODE支持欧洲、非洲、中东、亚洲(包括统一标准的东亚象形汉字和韩国象形文字)。但是,UNICODE并没有提供对诸如Braille, Cherokee, Ethiopic, Khmer, Mongolian, Hmong, Tai Lu, Tai Mau文字的支持。同时它也不支持如Ahom, Akkadian, Aramaic, Babylonian Cuneiform, Balti, Brahmi, Etruscan, Hittite, Javanese, Numidian, Old Persian Cuneiform, Syrian之类的古老文字。Unicode支持ISO Latin-1(ISO-8859-1),而Latin-1包含了ASCII编码表。

>utf-8(万国码,支持全世界的编码)

事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-7.5, UTF-8, UTF-16, 以及 UTF-32。

UTF-8只是Unicode编码的一种转换方式,这时因为Unicode问题占用两个字节的空间,而且最为常用的ASCII编码部分只需要一个字节就可以了,所以才会出现通用转换格式(UTF)。

UTF-8对不同范围的字符使用不同长度的编码,ASCII编码部分与ASCII一样,都是1个字节。而汉字部分都是3个字节。

Unicode转换到UTF-8规则如下:

  1. 如果Unicode编码的16位二进制数的前9位是0, 则UTF-8编码用一个字节来表示,这个字节的首位是0,剩下的7位与原二进制数据的后7位相同。例如:

Unicode编码:\u0061 = 00000000 01100001

UTF-8编码: 01100001 = 0x61

  1. 如果Unicode编码的16位二进制数的头5位是0,则UTF-8编码用2个字节来表示,首字节用110开头,后面的5位与原二进制数据去掉前5个零后的最高5位相同;第二个字节以10开头,后面的6位与原二进制数据的低6位数据相同。例如:

Unicode编码: \u00A9 = 00000000 10101001

UTF-8编码: 11000010 10101001 = 0xC2  0xA9

  1. 如果不符合上述两个规则,则用3个字节表示。第一个字节以1110开头,后四位为原二进制数据的高四位,第二个字节以10开头,后六位为原二进制数据的中间6位,第三个字节以10开头,后6位为原二进制数据的低6位。例如:

Unicode编码: \u4E2D = 01001110 00101101

UTF-8编码: 11100100 10111000 10101101 = 0xE4 0xB8 0xAD

把Unicode为 0101-1101 0001-0100 (5D14)

转换成UTF-8后为: 1110-0101 1011-0100 1001-0100 (E5B494)

编码相关功能

汉字“崔”的编码:

l GBK: 0xB4DE

l Unicode: 0x5D14

l UTF-8: 0xE5B494

1 获取字符串中所有字符的编码

String类的getBytes(String charName)方法可以用来获取当前字符串的据的字符的编码,返回值为字节数组。

l byte[] getBytes():返回GBK编码的字节数组;

l byte[] getBytes(String charsetName):返回指定编码的字节数组。该方法声明了UnsupportedEncodingException异常,该异常是IOException的子类,当Java不支持指定的编码时会抛出这个异常

byte[] b1 = “崔”.getBytes();// [-76, -34]

byte[] b1 = “崔”.getBytes(“GBK”);// [-76, -34]

byte[] b2 = “崔”.getBytes(“UTF-8”);// [-27, -76, -108]

byte[] b3 = “崔”.getBytes(“Unicode”);// [-2, -1, 93, 20],-2和-1是没有意义的。

  虽然上面使用的都是字符串“崔”,但获取的编码结果是不同的。这时因为Java使用相同的字符去查找不同的编码表得到的结果。

2 字符串类与字符编码

在Java中,字符都是使用Unicode编码(其实是UTF-16的一种方式),每个字符都占两个字节。而我们使用的OS都是使用GBK编码(当然,这需要你安装中文操作系统),也就是说文本文件中默认使用的都是GBK编码。

现在我们有一个字节数组,它表示的是GBK编码的汉字“崔”,例如:

byte[] buff = {-76, -34};

现在我们要把它转换成字符串,这需要使用String类的构造器:

String s = new String(buff, "GBK");

这个构造器需要指定字节数组,以及这个字节数组使用的编码表。其实,如果你不指定编码表,String类的构造器也会使用默认的编码表来把字节数组转换成字符串的。默认的编码表就是系统默认编码表,对中文操作系统来说就是GBK。

  new String(buff, “GBK”)的意思是:拿着buff这个编码,去查找”GBK”编码表,找到我们想要的字符,构成一个字符串。

byte[] buff = {-76, -34};

String s = new String(buff);

System.out.println(s);

上面代码打印的还是汉字“崔”。但如果你使用其他的编码表,例如使用UTF-8,那么一定会出现乱码。因为你的字节数组本身是对应GBK编码表的,但非要告诉String构造器去对照UTF-8编码表,那查出来的字符当前是错误的了!

乱码的出现,就是因为使用了错误的编码

要想不出现乱码:在调用getWriter()方法之前,要加上这一句即可:response.setContentType("text/html;charset=utf-8");

时间: 2024-10-03 23:59:18

常见字符编码的相关文章

Java web应用中的常见字符编码问题的解决方法

以下是 Java Web应用的常见编码问题 1. html页面的编码 在web应用中,通常浏览器会根据http header: Content-type的值来决定用什么encoding, 比如遇到Content-Type: text/html; charset=UTF-8, 页面使用的就UTF-8编码. 但是考虑到离线的html(用户可能把页面html保存到本地), 打开离线的html的时候就要在meta指定编码,当然不指定也会有default值,那么不指定有时就可能出现乱码. Meta标签 <

Python常见字符编码间的转换

学习Python,字符编码间的转换是绕不过去的一只拦路虎,不把编码彻底搞明白,总有一天它会猝不及防坑你一把. Python2.x和Python3.x在字符编码的设置上也有很大区别(Python3未来将是主流,所以Python3为主),今天我们就来一起学习下. 上一篇文章里我已经简述了Python的常见编码了,这里就不再赘述了,还不清楚的小伙伴可以先去看下:     http://www.cnblogs.com/schut/p/8406897.html 一.Unicode 和 UTF-8的纠葛 U

【转】关于字符编码,你所需要知道的(ASCII,Unicode,Utf-8,GB2312…)

转载地址:http://www.imkevinyang.com/2010/06/%E5%85%B3%E4%BA%8E%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%EF%BC%8C%E4%BD%A0%E6%89%80%E9%9C%80%E8%A6%81%E7%9F%A5%E9%81%93%E7%9A%84.html 字符编码的问题看似很小,经常被技术人员忽视,但是很容易导致一些莫名其妙的问题.这里总结了一下字符编码的一些普及性的知识,希望对大家有所帮助. 还是得从ASC

字符编码及java中的应用总结小记

这几日突然想搞清楚常见字符编码(ASCII.GBK.UTF.Unicode.ISO-8859-1)的关系及项目中可能存在的相关隐患,网上搜索了一大堆资料,这里结合代码实测,简单做个小结: 浅谈这几种编码的出现 1.1 ASCII 我们知道,在计算机内部,所有信息最终被表示为二进制字符串,每个二进制位有1和0两种表现形式,位是内存最小存储单位,其中8位构成一个字节,字节是数据存储的最小单元,因此8个二进制位即一个字节可以表示256个符号,从00000000-11111111. 上个世纪60年代,美

Python : 熟悉又陌生的字符编码(转自Python 开发者)

Python : 熟悉又陌生的字符编码 字符编码是计算机编程中不可回避的问题,不管你用 Python2 还是 Python3,亦或是 C++, Java 等,我都觉得非常有必要厘清计算机中的字符编码概念.本文主要分以下几个部分介绍: 基本概念 常见字符编码简介 Python 的默认编码 Python2 中的字符类型 UnicodeEncodeError & UnicodeDecodeError 根源 基本概念 字符(Character) 在电脑和电信领域中,字符是一个信息单位,它是各种文字和符号

关于字符编码,你所需要知道的(ASCII,Unicode,Utf-8,GB2312…)

字符编码的问题看似很小,经常被技术人员忽视,但是很容易导致一些莫名其妙的问题.这里总结了一下字符编码的一些普及性的知识,希望对大家有所帮助. 还是得从ASCII码说起 说到字符编码,不得不说ASCII码的简史.计算机一开始发明的时候是用来解决数字计算的问题,后来人们发现,计算机还可以做更多的事,例如文本处 理.但由于计算机只识“数”,因此人们必须告诉计算机哪个数字来代表哪个特定字符,例如65代表字母‘A’,66代表字母‘B’,以此类推.但是计算机之间字符-数字的对应关系必须得一致,否则就会造成同

ASCII,Unicode,GBK和UTF-8字符编码的区别和联系

如果经常写python2,肯定会遇到各种"奇怪"的字符编码问题,每次都通过谷歌解决了,但是为什么会造成这种乱码.decode/encode失败等等,本文就字符和字符编码做一个总结,更加清晰区分诸多的编码. 字符集 一个系统支持的所有抽象字符的集合.字符是文字和符号的总称,包含各个国家文字.标点符号.图像符号.数字等.它为每一个字符分配一个唯一的ID,一般称之为码位.码点. 字符编码 它是一套规则,使用该规则能够将自然语言的字符的一个集合与其他东西的一个集合进行配对,在符号集合和数字系统

字符编码(全-转)

字符编码的问题看似很小,经常被技术人员忽视,但是很容易导致一些莫名其妙的问题.这里总结了一下字符编码的一些普及性的知识,希望对大家有所帮助. 还是得从ASCII码说起 说到字符编码,不得不说ASCII码的简史.计算机一开始发明的时候是用来解决数字计算的问题,后来人们发现,计算机还可以做更多的事,例如文本处理.但由于计算机只识"数",因此人们必须告诉计算机哪个数字来代表哪个特定字符,例如65代表字母'A',66代表字母'B',以此类推.但是计算机之间字符-数字的对应关系必须得一致,否则就

字符集与字符编码详解

字符 字符和字节不太一样,任何一个文字或符号都是一个字符,但是所占字节不一定,不同的编码导致一个字符所占的内存不同. 例如:标点符号"+"是一个字符,汉字"我们"是两个字符,在GBK编码中一个汉字占2个字节,在UTF-8编码中一个汉字占3个字节. 随着时代的发展,程序员们希望在计算机中显示字符,但计算机只能识别0和1的二进制数.于是就有了编码规范. 编码规范 所谓的字符集其实是一套编码规范中的子概念,为了显示字符,国际组织就指定了编码规范,希望使用不同的二进制数来表