【转】ANSI与GB2312的编码问题
前两天和讨论字符编码的问题⼀直到深夜1点,主要是为了解决php读取⽂件的⼀个问题。可惜最后这个问题暂时没解决,先抛开这个问题,我在这⾥总结⼀下我对字符编码的认识。
⽂件编码与字符编码
⾸先明确⼀点,⽂件不存在什么编码(归根结底⽂件都是⼆进制⽂件,⽤ue打开可以看到都是⼀个个的16进制数),只有⽂件中的字符才可以说编码。
编码与解码过程
字符通过某种编码组织起来存到⽂件⾥⾯,计算机通过这种编码解析解析⽂件,根据解析出来的⽂字绘制图⽚显⽰到显⽰设备中,这样我们就看到了⽂字。
常见编码介绍
ansi编码
最初的计算机是⼜8个晶体管,通过晶体管的开合与排列可以表⽰数种状态,所以⼀个字节就定义为8bit,⽽⼀个bit只能有0,1开关的表⽰,2的8次⽅是256,所以最初的计算机只能表⽰256种状态。
GB2312与GBK
国⼈发现只使⽤ASCII表根本⽆法表⽰汉字!怎么办?没有什么能难道我们!于是我们发明了GB2312编码,此编码完全忽略了ASCII表中127位后⾯的内容,127位前⾯的内容保留,如果两个字节同时⼤于127(7F)就认为这两个字节表⽰⼀个汉字,同时像标点、字母也都重新使⽤两个字节 定义了⼀遍,这就是我们经常说的 全⾓,这种⽅案可以表⽰6000种⽂字。
但是中国的⽂字太复杂6000个字也不够⽤,⼈们开始扩展GB2312,规定只要⼀个字节⼤于127,这个字节和后⾯的字节组合起来就代表⼀个汉字,这种编码成为GBK,于是⼜增加了20000多个汉字!
现在明⽩的⾥为什么有GB2312与GBK了吧?:)
<meta http-equiv="content-type" content="text/html; charset=GB2312" />
<meta http-equiv="content-type" content="text/html; charset=GBK" />
这样很多国家都开始定义⾃⼰的编码了,⽇本,韩国等。甚⾄连中国的台湾省都定义了⼀种编码 BIG5。所以在当时⼀个程序要想适应多国语⾔简直要把⼈郁闷死。
如果搞过windows编程的⼈应该知道,win⾥⾯有多字节字符集MBCS(multi-byte character set)的说
法,⽽且MBCS包含两种字符类型,单字节字符SBCS(single-byte characters set)和双字节字符(double-byte characters set)DBCS。我们的GBK与GB2312都是DBCS。所以我们在编程时经常遇到⼀个中⽂字符等于两个英⽂字符的事情。BIG5与⽇本韩国的编码也 都属于DBCS。
这下清楚了吧,根本没什么ansi⽂件或gb2312⽂件,⽂件打开时会根据操作系统的编码⽅式(就是安装在操作系统中的编码解析⽅式)来尝试打开⽂件,如果安装了中⽂编码,就把ansi⽂件当作中⽂打开,如果⽇⽂编码,就当作⽇⽂打开。
UNICODE与UTF-8
ISO最后提出了UNICODE(Universal Multiple-Octet Coded Character Set,简称 UCS)编码来解决所有的问题。
UNICODE编码⽅式规定使⽤两个字节(16位)表⽰表⽰⼀个字符,算算2的16次⽅是多少?原来ANSI规定的都扩充为2字节,并且把所有已知的语⾔都编码进UNICODE。UNICODE可以表⽰65536个字符。
这下多国语⾔程序开始⾼兴了,使⽤UNICODE全部搞定!于是微软重现编辑windows内核,完全使⽤UNICODE编码,搞过win编程的⼈应该都知道,以A或W结尾的函数,还有灵巧的_T宏吧?
虽然UNICODE有很多优点,但是缺点也不少,我先总结我知道的两点:
1,狂占空间,以前⼀个字节可以表⽰,现在却要⽤两个字节了,⽹络上有80%属于英⽂字符,这下⽹络⼏乎要扩⼤⼀倍!
所以⼜有⼈研究出来了UTF-8(Unicode Translation Format - 8)编码,UNICODE转换格式,对于常⽤字符使⽤单字节,汉字等使⽤双字节。8代表每次在⽹络上传输8位,如果是UTF-16就是每次传输16位。搞 过⽹络编程的朋友应该知道,字节序(就是字节的排放顺序)分为两种,主机字节序与⽹络字节序,就是⼤头(俗称)在前,⼩头在前的问题,在⽹络上⾯传输的流 的字节序很可能是不⼀致的,于是需要使⽤⼀种⽅法通知接收端,传输流的字节序。有⼈发明了⼀种简单的⽅法,在每个流的开始加上FFEF或EFFF,分别主 机与⽹络字节序,我们可以使⽤记事本保存⼀个UNICODE⽂件,再使⽤ue打开看看(HEX⽅式打开)。所以有时候⽹页传到⽹上,在⽹页最开始的地⽅会 出现⼀个字符,这个有时候很令⼈费解。
⽤记事本新建⽴两个⽂件存为UNICODE与UNICODE big endian模式,输⼊梦之都,保存再⽤ue打开。
UNICODE
FF FE A6 68 4B 4E FD 90
UNICODE big endian
FE FF 68 A6 4E 4B 90 FD (观察,没两个字节和上⾯的对⽐)
2,UNICODE与GBK等两字节编码完全不兼容,⽆法到⼀种简单的⽅式转换(只能使⽤查表的⽅式)
这点我们可以使⽤记事本新建⽴两个⽂件⼀个ansi的⽂件,另⼀个utf8的⽂件,分别写⼊梦之都 ,保存。使⽤ue的hex模式打开我们会看到。
UNICODE
FF FE A6 68 4B 4E FD 90
ansi
C3 CE D6 AE B6 BC
猜编码
在windows系统中打开⽂件时,是使⽤了猜的⽅式选择解析⽂件内容编码系统,如果⽂件开头使⽤了FEFF或FFFE,win系统认为UNICODE编码,否则为ANSI编码,如果是ANSI编码继续分析,如果⼀个字节⼤于127,就证明这个字节与后⾯的字节组成了⼀个汉字。
所以windows中⽂系统下,如果ansi⽂件,那么就会⽤gb2312⽅式转换,如果是⽇⽂系统,就会使⽤⽇⽂⽅式转变,但是绝对不能说ansi ⽂件⾥⾯有中⽂字符就是gb2312!⼀个gb2312占⽤两个字节。⽽utf8 win系统在前⾯加了⼏个字节以⽰区别。unicode汉字
通过这种⽅式分析时会产⽣⼀个很著名的问题,如果⽤记事本输⼊“联通”保存,再打开,发现“联通”两个字没了!为什么没有了,⼤家可以⾃⼰分析⼀下。有⼈说这就是联通竞争不过移动的原因。
通过这篇⽂章解决的⽹页设计中的问题
1,⼀个汉字等于两个字符,对吗?
2,为什么页⾯或页⾯的开始会有乱码?
3,GB2312与GBK的区别
4,为什么英⽂多的⽹站使⽤UTF-8⽐GB2312省空间?

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。