`

GBK,UTF-8,和ISO8859-1之间的编码与解码

    博客分类:
  • java
阅读更多

Unicode、UTF-8 和 ISO8859-1到底有什么区别

 

将以"中文"两个字为例,经查表可以知道其GB2312编码是"d6d0 cec4",Unicode编码为"4e2d 6587",UTF编码就是"e4b8ad e69687"。注意,
这两个字没有iso8859-1编码,但可以用iso8859-1编码来"表示"。 

2. 编码基本知识 

最早的编码是iso8859-1,和ascii编码相似。但为了方便表示各种各样的语言,逐渐出现了很多标准编码,重要的有如下几个。 

2.1. iso8859-1 通常叫做Latin-1

属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母a的编码为0x61=97。 

很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,
仍旧使用iso8859-1编码来表示。而且在很多协议上,默认使用该编码。比如,虽然"中文"两个字不存在iso8859-1编码,以gb2312编码为例,应
该是"d6d0 cec4"两个字符,使用iso8859-1编码的时候则将它拆开为4个字节来表示:"d6 d0 ce c4"(事实上,在进行存储的时候,也是以字节为
单位处理的)。而如果是UTF编码,则是6个字节"e4 b8 ad e6 96 87"。很明显,这种表示方法还需要以另一种编码为基础。 

2.2. GB2312/GBK 

这就是汉子的国标码,专门用来表示汉字,是双字节编码,而英文字母和iso8859-1一致(兼容iso8859-1编码)。其中gbk编码能够用来同时表示
繁体字和简体字,而gb2312只能表示简体字,gbk是兼容gb2312编码的。 

2.3. unicode 

这是最统一的编码,可以用来表示所有语言的字符,而且是定长双字节(也有四字节的)编码,包括英文字母在内。所以可以说它是不兼容iso8859-1编
码的,也不兼容任何编码。不过,相对于iso8859-1编码来说,uniocode编码只是在前面增加了一个0字节,比如字母a为"00 61"。 

需要说明的是,定长编码便于计算机处理(注意GB2312/GBK不是定长编码),而unicode又可以用来表示所有字符,所以在很多软件内部是使用unicode
编码来处理的,比如java。 

2.4. UTF 

考虑到unicode编码不兼容iso8859-1编码,而且容易占用更多的空间:因为对于英文字母,unicode也需要两个字节来表示。所以unicode不便于传输和存
。因此而产生了utf编码,utf编码兼容iso8859-1编码,同时也可以用来表示所有语言的字符,不过,utf编码是不定长编码,每一个字符的长度从1-6个字

节不等。另外,utf编码自带简单的校验功能。一般来讲,英文字母都是用一个字节表示,而汉字使用三个字节。 

注意,虽然说utf是为了使用更少的空间而使用的,但那只是相对于unicode编码来说,如果已经知道是汉字,则使用GB2312/GBK无疑是最节省的。不过另
一方面,值得说明的是,虽然utf编码对汉字使用3个字节,但即使对于汉字网页,utf编码也会比unicode编码节省,因为网页中包含了很多的英文字符。 

3. java对字符的处理 

在java应用软件中,会有多处涉及到字符集编码,有些地方需要进行正确的设置,有些地方需要进行一定程度的处理。 

3.1. getBytes(charset) 

这是java字符串处理的一个标准函数,其作用是将字符串所表示的字符按照charset编码,并以字节方式表示。注意字符串在java内存中总是按unicode编码
存储的。比如"中文",正常情况下(即没有错误的时候)存储为"4e2d 6587",如果charset为"gbk",则被编码为"d6d0 cec4",然后返回字节"d6 d0 ce c4"。
如果charset为"utf8"则最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1",则由于无法编码,最后返回 "3f 3f"(两个问号)。 

3.2. new String(charset) 

这是java字符串处理的另一个标准函数,和上一个函数的作用相反,将字节数组按照charset编码进行组合识别,最后转换为unicode存储。参考上述getBytes
的例子,"gbk" 和"utf8"都可以得出正确的结果"4e2d 6587",但iso8859-1最后变成了"003f 003f"(两个问号)。 

因为utf8可以用来表示/编码所有字符,所以new String( str.getBytes( "utf8" ), "utf8" ) === str,即完全可逆。 

3.3. setCharacterEncoding() 

该函数用来设置http请求或者相应的编码。 

对于request,是指提交内容的编码,指定后可以通过getParameter()则直接获得正确的字符串,如果不指定,则默认使用iso8859-1编码,需要进一步处理。
参见下述"表单输入"。值得注意的是在执行setCharacterEncoding()之前,不能执行任何getParameter()。java doc上说明:This method must be called prior to reading request parameters or reading input using getReader()。而且,该指定只对POST方法有效,对GET方法无效。 分析原因,应该是在执行第一个getParameter()的时候,java将会按照编码分析所有的提交内容,而后续的getParameter()不再 进行分析,所以setCharacterEncoding()无效。而对于GET方法提交表单是,提交的内容在URL中,一开始就已经按照编码分析所有的 提交内容,setCharacterEncoding()自然就无效。

 

4.iso-8859-1是JAVA网络传输使用的标准 字符集,而gb2312是标准中文字符集,当你作出提交表单等需要网络传输的操作的时候,就需要把 iso-8859-1转换为gb2312字符集显示,否则如果按浏览器的gb2312格式来解释iso-8859-1字符集的话,由于2者不兼容,所以会 是乱码.

 

最后来看一个编码的例子:

 

  1. String s = "你好";  
  2.   
  3. // 编码  
  4. byte[] utf = s.getBytes("utf-8");  
  5. byte[] gbk = s.getBytes("gbk");  
  6.   
  7. System.out.println("utf-8编码:" + Arrays.toString(utf)); // [-28, -67, -96, -27, -91, -67]  6个字节  
  8. System.out.println("gbk编码:" + Arrays.toString(gbk)); // [-60, -29, -70, -61]<span style="white-space:pre">  </span>4个字节  
  9.   
  10. // 解码  
  11. String s1 = new String(utf, "utf-8"); // 你好  
  12. String s2 = new String(utf, "gbk");// gbk解码:浣犲ソ gbk用2个字节解码,所以会多一个字符  
  13. String s3 = new String(gbk, "utf-8");// gbk用utf-8解码:??? <span style="white-space:pre">  </span>utf-8解码需要6个字节  
  14.   
  15. System.out.println("--------------------");  
  16. System.out.println("utf-8解码:" + s1);  
  17. System.out.println("gbk解码:" + s2);  
  18. System.out.println("gbk用utf-8解码:" + s3);  
  19. System.out.println("---------------------");  
  20.   
  21. System.out.println("用utf-8编码回去");  
  22.   
  23. s3 = new String(s3.getBytes("utf-8"), "gbk");  // 锟斤拷锟?   gbk用utf-8解码后无法编回去  
  24.   
  25. System.out.println(s3);  

规律:

 utf-8编码可以用gbk和iso8859-1解码后编回去
gbk编码后只能用iso8859-1解码后编回去

 

在JSP页面获取表单的值时会出现乱码,有两种解决方法:

一种是在调用getParameter之前通过 request.setCharacterEncoding设置字符编码,另一种是调用new String(str.getBytes("iso8859-1"), "UTF-8");编码后解码,这两种方法都可以得到正确的结果

分享到:
评论

相关推荐

    DELPHI 10.3编码转换 iso-8859-1转GBK,GBK转iso-8859-1

    例如,如果二维码生成器默认使用`UTF-8`编码,而输入的数据是`ISO-8859-1`或`GBK`编码,解码时就会出现错误。因此,正确地进行编码转换至关重要。 解决乱码问题的方法是确保在生成二维码前将数据转换为统一的编码...

    JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换

    本文将详细介绍Unicode、ISO-8859-1、GBK和UTF-8这四种常见的字符编码,并探讨它们之间的转换方法。 #### 二、基础知识 ##### 1. Unicode Unicode是一种国际字符编码标准,旨在支持世界上几乎所有语言的文字。它为...

    各种字符集编码表,包括iso-8859-1,gbk,gb18030, unicode

    2. GBK:GBK是中国大陆广泛使用的汉字编码标准,是对GB2312的扩展,兼容ASCII和ISO-8859-1。GBK包含约20,902个汉字和图形符号,可以满足简体中文的大部分需求。 3. GB18030:GB18030是GBK的进一步扩展,支持更多的...

    ISO8859-1字符集与其他字符集兼容性测试

    在这个测试中,我们将探讨ISO8859-1字符集与其他常见的字符集,如UTF-16、UTF-8、GBK和GB2312之间的相互兼容性。 ISO8859-1,也称为Latin-1,是ISO8859系列标准的一部分,它覆盖了西欧语言的基本拉丁字母,包括...

    java 解决异常 2 字节的 UTF-8 序列的字节2 无效的问题

    1. **文件编码不正确**:文件可能被错误地标识为UTF-8编码,但实际内容可能是其他编码,比如GBK或ISO-8859-1。这会导致解析器在尝试解码时出现问题。 2. **数据损坏**:文件或网络传输过程中可能发生了错误,导致...

    ebms_dll_pbbase64加密解密_Base64.dll_Base64utf-8

    在处理字符串时,有时需要将UTF-8编码的字符串与其他编码(如GBK、ISO-8859-1等)互相转换。这个过程就是“转码”,确保数据在不同系统或应用之间正确显示和处理。 “ebms_dll.dll”可能是另一个动态链接库,可能...

    html转utf8转码器

    如果HTML文件以非UTF-8编码保存,如GBK或ISO-8859-1,当浏览器使用UTF-8解析时,就会出现乱码。反之,如果HTML文件声明了错误的编码,也会导致相同问题。 "Html文件转UTF8编码工具"的工作原理一般如下: 1. 打开...

    UTF8与ansi string转换处理(DELPHI7开发)

    而ANSI String通常指的是基于特定区域设置的单字节编码,如Windows默认的GBK或ISO-8859-1。 在描述中提到的“delphi 开发的UTF8 ansistring转换动态库”是一个由DELPHI编写的DLL文件,名为UTF8_DLL.dll。DLL文件...

    中文乱码解决方案归纳.pdf

    GBK、UTF-8和ISO-8859-1之间的转换需要注意,偶数个汉字可以在GBK和UTF-8之间互换,而奇数个汉字可能在转换过程中丢失,导致乱码。 总的来说,将Tomcat的`URIEncoding`设置为`UTF-8`是解决大多数中文乱码问题的有效...

    解决Tomcat中文乱码

    Tomcat默认使用的字符集是ISO-8859-1,而大多数中文网页和文件采用的是GBK或UTF-8编码。当Tomcat处理这些中文内容时,如果没有正确地转换编码,就会出现乱码问题。 #### 原因分析 1. **默认字符集问题**:Tomcat...

    javascript经典特效---编码互换.rar

    最常用的编码格式有ASCII、ISO-8859-1、GB2312、GBK以及Unicode的实现UTF-8等。在网页开发中,不正确的编码可能导致乱码问题,因此理解和掌握编码转换至关重要。 在JavaScript中,我们可以使用`decodeURIComponent...

    ibatis乱码解决方法(ibatis独立)

    本文将详细讨论如何解决Ibatis中的乱码问题,特别是涉及到GBK和ISO_8859_1编码格式时的解决方案。 首先,我们需要了解乱码产生的原因。乱码通常是因为字符编码不一致导致的。在Java和数据库之间进行数据交互时,...

    java字符集编码问题

    通过对ISO 8859-1、GB2312/GBK、Unicode和UTF等常见编码的理解,以及Java提供的字符串操作方法(如`getBytes`和`new String`),开发者可以有效地解决实际项目中的字符编码问题,确保应用程序能够正确地处理各种文本...

    Java Web中请求消息和响应消息中文乱码问题的研究与对策.pdf

    解决办法是手动使用ISO-8859-1重新编码接收到的参数,然后用UTF-8解码,例如`new String(name.getBytes("ISO8859-1"), "UTF-8")`。 对于响应消息的中文乱码,主要是响应体的编码设置。在Servlet中,可以使用...

    JSP中文解码方法

    - POST请求的数据通过`request`对象存储,如果未设置请求体的编码,服务器默认使用ISO-8859-1解码,可能导致乱码。 - 解决方法:在接收页面,通过`request.setCharacterEncoding("UTF-8")`设置请求编码,或者全局...

    java中编码的转换

    本文将深入探讨在Java中处理字符编码,尤其是UTF-8和GBK编码的转换技巧,以及如何在不同的场景下(如JSP页面与纯Java类文件)确保中文的正确显示。 ### 一、数据库连接方式与字符编码 #### 1. 使用UTF-8进行数据库...

    Python-Decodify递归地检测和解码编码的字符串

    Decodify的工作原理是,它会尝试一系列常见的文本编码,如ASCII、ISO-8859-1、UTF-8、GBK等,直到找到一个可以成功解码整个字符串的编码。如果遇到部分编码的子字符串,它会继续对这部分进行递归解码,直到所有部分...

    JAVA及相关字符集编码问题

    正确理解和应用不同的字符集编码标准,如ISO8859-1、GB2312/GBK、Unicode和UTF-8,是确保数据在不同系统和平台之间正确传输的基础。在实际开发中,应根据具体需求选择合适的字符集编码,并注意在不同环节保持字符集...

    Java文件编码转换源码

    描述中提到,这个示例已经测试了GB2312到UTF-8以及UTF-8到GB2312的转换,但不支持ISO-8859-1编码。ISO-8859-1是一种单字节编码,主要用于西欧语言,如果需要支持,只需要将`Charset.forName()`中的编码名替换为"ISO-...

Global site tag (gtag.js) - Google Analytics