`
方块石
  • 浏览: 60010 次
  • 来自: ...
社区版块
存档分类
最新评论

乱码的编码原理

阅读更多
个人理解部分:能力有限,不保证正确性,只为自己理解
*************************************************************************
计算机不认识a,b,c,1,2,3,中国,等等,必须要转换成010101这种计算机识别的。
因此要对a,b,c,1,2,3,中国 这些进行编码,按照一定的规范,把这些字符转成010101,
ascii,unicode就是这类规范,ascii只规定 一个字符 表示一个字节,(而一个字节由8bit组成),
因此 ascii就只能表示 从 0000 0000 到  1111 1111 这么多个字符,也就是 2*2*2*2  * 2*2*2*2 个
(1,2,用ascii表示 可能是49,50,然后再转换成二进制数010101之类的,11表示的是两个字符)
如果只表256个字符, 但是汉字就不能表示了。
unicode 规定 一个字符 由两个 字节组成,因此 他可表示的字符就有 2的16次方个,(因为一个字节8bit,2字节
16bit,0000 0000 0000 0000 这表示一个字符,可能规定表示的是字母 a,或是A,具体看unicode怎么定义的)

new String("1").getBytes() [49]
new String("11").getBytes() [49,49]
new String("a").getBytes() [97]
new String("A").getBytes() [65]
"中".getBytes("UTF-8") [-28, -72, -83]
"中a".getBytes("GBK") [-42, -48, 97]
"中a".getBytes("UTF-8") [-28, -72, -83, 97]
*************************************************************************
以下为网上摘抄:从原理上理解

uft-8 三个字节表示一个汉字
GBK,两个字节表示一个汉字

GBK兼容GB2312
UTF-8自动兼容ASCII
UTF-8是UNICODE的一种变长字符编码

传统的英文编码,最常见的就是两种。一是ASCII,这种字符集高位为0,用7位表示数据。另一种是ISO-8859-1,每个字符1字节,用8位表示一个字符。

程序文件在保存时默认采用了操作系统默认支持GBK编码格式(操作系统默认支持的格式为file.encoding格式)形成了一个.java文件,也即,java程序在被编译前,我们的JAVA源程序文件是采用操作系统默认支持的file.encoding编码格式保存的



在UTF-8里,英文字符仍然跟ASCII编码一样,因此原先的函数库可以继续使用。而中文的编码范围是在0080-07FF之间,因此是2个字节表示(但这两个字节和GB编码的两个字节是不同的),用专门的Unicode处理类可以对UTF编码进行处理。

UTF-8有点类似于Haffman编码,它将Unicode编码为00000000-0000007F的字符,用单个字节来表示;

00000080-000007FF的字符用两个字节表示

00000800-0000FFFF的字符用3字节表示
因此utf-8是变长编码的,   汉字用uft-8为三个字节




以目前常用的UCS-2为例,它可以表示的字符数为2^16=65535,基本上可以容纳所有的欧美字符和绝大部分的亚洲字符 。

在Unicode里,所有的字符被一视同仁。汉字不再使用“两个扩展ASCII”,而是使用“1个Unicode”,注意,现在的汉字是“一个字符”了,于是,拆字、统计字数这些问题也就自然而然的解决了 。

但是,这个世界不是理想的,不可能在一夜之间所有的系统都使用Unicode来处理字符,所以Unicode在诞生之日,就必须考虑一个严峻的问题:和ASCII字符集之间的不兼容问题。

我们知道,ASCII字符是单个字节的,比如“A”的ASCII是65。而Unicode是双字节的,比如“A”的Unicode是0065,这就造成了一个非常大的问题:以前处理ASCII的那套机制不能被用来处理Unicode了 。

另一个更加严重的问题是,C语言使用'\0'作为字符串结尾,而Unicode里恰恰有很多字符都有一个字节为0,这样一来,C语言的字符串函数将无法正常处理Unicode,除非把世界上所有用C写的程序以及他们所用的函数库全部换掉 。


3个uft-8的汉字  9个字节   用GBK表示 只能用8个字节来转码  因此会有一个字乱码
utf-8表示字母是一个字符占一个字节

new String("中国").getBytes("utf-8")  --> [-28, -72, -83, -27, -101, -67]
一个字节8个bit,由8个二进制数表示, 这只是uft-8规定的编码格式
(一下为个人理解)
交由计算机处理时,计算机识别为uft-8,则把三个字节的二进制  作为一个单位。
而单纯的数字和字母,uft-8则由一个字节表示, 那三个数字一起 会不会误认为是一个汉字呢?
肯定不会,因为 三个字节一起组成汉字时,uft-8编码会在每个字节的高位做标识。
而数字和字母的  单字节的  应该也是有 标识的


如果是2个utf-8的汉字 占6个字节   转码GBK  也可以用6个字节来转码,刚好转码,因此不会乱码

iso-8859-1  一个

然而看看新浪、淘宝等大型网站好像还是顽固不化地在使用gb2312,是不是它们太落伍了?答案当然不是。对编码方式了解的人都知道,UTF8编码存储一个汉字需要3-4个字节,而GBK只需2个字节。这样对于同一个页面,使用UTF8编码就需要多耗费50%-100%的带宽,100G的数据则需要 150G-200G的硬盘才能装下。了解了这些,那些对带宽、硬盘空间斤斤计较的人,可能就会对UTF8望而却步了。


如果是按字节来分批读取,不光是utf-8编码,gbk也是会有问题的,两个汉字是4个字节,而一个英文字母加一个汉字是3个字节,所以不可能每次都刚好从两个字符之间切开,除非所有字符都是汉字,可以按双数来取。
所以必须把字节流全部加载进来,整体一起转换成字符串。

如果事先知道字符编码,那么可以用楼上的简单方法,按字符来读取,读出来的都是完整的字符。

如果事先不知道编码格式,但是像xml文件头中注明了编码格式,那么可以按iso-8859-1的编码格式将读进来的字节流进行字符化,然后根据读到的encoding得到编码格式,按照正确的编码格式重新将读到的内容整体转换成正确的字符串。
因为iso-8859-1格式一个字节对应一个字符,并且每一个字节值都有一个对应的字符,将字符还原到字节时原来的值不会发生改变,所以按字节分批读取也不会破坏数据的完整性。并且gbk和utf-8都是兼容iso-8859-1的,即基本字符的编码是一样的,所以按iso-8859-1编码得到的encoding那一段字符是正确的,可识别的。
也可以只读取一个头部,找到正确的编码格式后,再用InputStreamReader按字符读取。





××××××××××××××××××××××××××8

JSP Compiler一般是用InputStreamReader来读取文件的,指定了pageEncoding之后,也就指定了InputStream的charset,所以pageEncoding指定的正是文件本身的encoding。


其实FileReader/FileWriter是根据默认的文件字符编码directive  file.encoding 来编码读取/写入文件流的


读写文件是按系统默认的字符编码, file.encoding
分享到:
评论

相关推荐

    乱码,编码转换器

    它可能提供了用户友好的界面,使得用户无需深入了解编码原理就能进行转换操作。在虚拟机中运行该工具,可以隔离可能存在的安全风险,比如未知的病毒或恶意软件,因为虚拟机可以提供一个沙盒环境,即使软件有问题,也...

    jsp编码 jsp乱码

    因此,了解jsp编码的原理和解决乱码问题的方法是非常重要的。 jsp编码的原理 jsp编码是指jsp页面中的编码方式,jsp页面可以使用不同的编码方式,如UTF-8、GBK等。jsp编码的原理是jsp页面在编译成Servlet时使用的...

    javaweb servlet(jsp)的乱码问题原理及解决

    ### javaweb servlet(jsp)的乱码问题原理及解决 #### HTTP协议的基本理解与乱码问题背景 HTTP协议作为互联网应用中最为广泛使用的通信协议之一,它定义了客户端和服务端之间的交互规则。HTTP请求主要分为GET和...

    韩文乱码转换器

    在处理韩文乱码问题时,除了使用转换工具,理解字符编码的基本原理也很重要。例如,理解什么是字节顺序标记(BOM)、如何在编程语言中设置正确的编码设置等,这些都对防止乱码产生有帮助。同时,对于开发人员来说,...

    有关pdfbox-1.3.1中Identity-H编码为乱码的解决方法

    记住,处理PDFBox和Identity-H编码问题可能需要深入理解PDF规范以及字符编码原理,但通过上述方法,你应该能找到解决问题的途径。如果问题依然存在,建议详细检查代码和文档,或者寻求社区和开发者论坛的帮助。

    彻底解决中文乱码的问题

    然而,每个具体问题可能需要针对性的解决方案,因此在实际工作中,了解并熟练掌握字符编码原理,结合具体情况调整代码,才能真正做到“彻底解决中文乱码问题”。 在提供的压缩包文件“中文乱码的问题决绝.doc”中,...

    常见编码及乱码的处理.pdf

    编码、字符、字符集和乱码处理...在处理编码和乱码问题时,需要对编码原理有清晰的理解,结合具体的使用场景选择合适的编码和字符集,同时注意编码的转换过程和规则。只有这样,才能保证信息的准确传递和数据的一致性。

    日文乱码转换工具

    3. **Locale Emulator的工作原理**:Locale Emulator通过模拟不同的区域设置环境来运行程序,使得应用程序误以为当前的系统环境支持其需要的字符编码,从而避免乱码问题。它可以独立于系统设置运行,避免了全局更改...

    JSP和Servlet中的几个编码的作用及原理

    本文将深入探讨JSP和Servlet中的几个关键编码设置的作用及原理,帮助开发者更好地理解和解决实际开发中遇到的编码问题。 #### 二、主要编码设置及其作用 ##### 1. `pageEncoding="UTF-8"` - **作用**:`...

    细说编码,检索乱码的一个ppt

    编码是计算机处理文字和信息的关键技术,尤其在涉及多种语言和字符集的环境下,理解编码原理对于解决乱码问题至关重要。本篇将深入探讨编码的概念,着重介绍汉字编码和相关乱码问题。 首先,编码是一种将字符按固定...

    js实现GBK编码,解决乱码

    在JavaScript(JS)环境中,GBK编码...总的来说,解决JS中的GBK编码问题需要理解编码原理,并可能借助第三方库或自定义函数。通过正确地编码和解码,可以在使用GBK编码的环境中顺利地传递和显示数据,避免乱码的出现。

    winform的字符串转换乱码解决

    处理Winform应用中的字符串转换乱码问题,关键在于理解字符编码的工作原理并正确地在各个层面使用它。从文件读取到数据展示,每个环节都要确保编码的一致性。通过细心排查和合理设置,乱码问题可以得到有效解决。 ...

    常用字符集编码原理及解决方法

    理解字符集编码的原理和特性对于解决乱码问题、进行文本处理以及跨平台通信至关重要。 首先,ASCII编码是最基础的字符集,它是一种7位的编码,覆盖0x00到0x7F的二进制范围,包含了英文字符、数字和一些标点符号。在...

    jsoncpp 写入乱码解决版本

    因此,理解字符编码的基本原理,以及如何在C++中处理它们,对于避免和解决乱码问题至关重要。JSONCPP库提供了一套API来方便JSON数据的处理,但用户仍需关注编码问题,以确保数据的正确性。 在提供的压缩包文件...

    乱码算法大全 txt文档

    本文将对互联网上最常用的几种编码方式的编码与解码算法进行详细的讲解,旨在为想要深入了解乱码算法原理及其编程实现的朋友提供有价值的参考。本文提供的源代码采用C语言编写,以函数的形式呈现,便于直接调用。 #...

    JSP编码以及乱码问题解疑

    **JSP编码与乱码问题详解** 在JSP(JavaServer Pages)开发中,编码问题是一个常见的困扰,尤其是在处理中文字符时。本文将深入探讨JSP编程...了解这些原理和解决方案,可以帮助开发者避免因编码问题引发的诸多不便。

    解决rf中文乱码问题

    解决这个问题需要深入理解编码原理,并采取适当的策略来确保正确地处理中文字符。 首先,我们要了解编码的基础知识。在计算机中,中文字符通常由Unicode编码表示,最常见的是UTF-8格式。UTF-8是一种变长的字符编码...

Global site tag (gtag.js) - Google Analytics