字符编码及乱码介绍
作者:binary
2011-04
字符编码
字符编码的进化史
各种乱码
参考资料
基本概念
字符(character)即文字不符号,是人们使用的记号,抽象意义上的一个符号。如’a’,‘中’,‘¥’等
字符集(charset)字面上的理解就是字符的集合,例如ASCII字符集,定义了128个字符。但准确来说,指的是已编号的字符的有序集合
字符码/代码点(code point)指的就是字符集中每个字符的数字编号
字符编码(character encoding)是将字符集中的字符码映射为字节流的一种具体实现方案
汉字内码是在设备和信息处理系统内部存储、处理、传输汉字用的代码。无论使用何种输入码,进入计算机后就立即被转换为机内码。计算机使用的缺省编码方式就是计算机内码
字符编码
字符编码
ASCII
American Standard Code for Information Interchange(美国信息转换标准代码)
最通用的单字节编码系统,最高位为0,等同于国际标准ISO 646
范围:0x00 -0x7F(共128个字符)
控制字符:33个(0x00 -0x1F, 0x7F)
可见字符:95个(0x20 -0x7E)a-z, A-Z, 0-9等
# man ascii
英文使用ASCII足够
字符编码
扩展的ASCII / OEM字符集
单字节编码系统,把第8位利用起来,产生了各种OEM字符集(混乱)
范围:0x00 -0xFF
大部分OEM字符集不ASCII兼容CODE PAGE:对于128-255字符码,根据你所在国家/地区的不同,会有不同的处理方式。我们称这样相异的编码系统为代码页(code pages)
ISO-8859-1(Latin1)是8位单字节编码的国际标准
7GB2312GB -> 国标,1981.5.1,《信息交换用汉字编码字符集. 基本集》中国国家标准的简体中文字符集(国标码)DBCS(双字节字符集)高字节0xA1 -0xF7,低字节0xA1 -0xFE兼容ASCII收入汉字6763个,符号715个,总计7478个字符覆盖99.75%使用频率全角:在ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的”全角”字符半角:原来在127号以下的那些就叫”半角”字符了通行于大陆、新加坡等地也采用此编码
BIG-5
大五码
1984年,由台湾的宏碁等五大软件公司创建BIG-5码
F4(Flower-4)的取名学BIG-5么^_^
DBCS(双字节字符集)
高字节0xA1 -0xF9,低字节0x40 -0x7E, 0xA1 -0xFE
兼容ASCII
收入13060个繁体汉字,808个符号,总计13868个字符(包括了无简体与繁体之分的传统传承汉字)
目前普遍使用于台湾、香港等地区
GBK
GB=GuoBiao,K=扩,1995年
可以同时表示繁体字(不BIG-5不兼容)和简体字
DBCS(双字节字符集)
高字节0x81 -0xFE,低字节0x40 -0xFE
兼容ASCII、兼容GB2312
收入汉字21003个、符号883个,总计21886个字符
GB18030
《信息交换用汉字编码字符集基本集的扩充》,2000年
变长编码
单字节、双字节、四字节编码
单字节:0x00 -0x7F
双字节:高0x81 -0xFE,低0x40 -0x7E,0x80 -0xFE
四字节:一、三字节为0x81 -0xFE,二、四字节为0x30 -0x39
覆盖了所有unicode编码
目前的国家标准
单字节、双字节和GBK、GB2312完全兼容
总编码空间超过150万个
收入汉字27484个、覆盖中、日、韩和中国少数民族文字。
小结:
每种语言都制定了自己的字符集,最后导致存在的各种字符集实在太多。
ANSI组织制定了ANSI标准字符编码
ASCII字符集,以及由此派生幵兼容的字符集我们称其为ANSI字符集
Windows中通常说到的ANSI编码,通常指的是系统设置的默认编码,例如英文操作系统中是ISO-8859-1,中文系统是GBK,日文系统用的是JIS
不便:
1. 在国际交流中要经常转换字符集非常不便
2. 不能在一份文档中显示所有字符
UNICODE
Universal Multiple-Octet Coded Character Set通用多字节编码字符集
简称UCS(Unicode Character Set ),万国码
涵盖目前人类使用的所有字符
为每一种语言中的每一个字符设定统一幵且唯一的字符码(code point)
编码方式、实现方式
兼容ASCII(更准确地说,是不ISO-8859-1兼容)
不兼容ANSI编码(GBK、JIS)
UCS结构
编码方式UCS-2 vs. UCS-4
UCS-2
字符和代码点之间的对应关系就是UCS-2(Universal Character Set coded in 2 octets)
代码点U+ABCD
范围:U+0000 ~ U+FFFF(定长2字节)2^16=65536
UCS-4
为了能表示更多的文字
范围:U+00000000~U+7FFFFFFF(定长4字节,最高位为0)
2^31 = 2147483648
U+00000000~U+0000FFFF和UCS-2是一样的
UCS-2和UCS-4只规定了代码点和字符之间的对应关系,幵没有规定代码点在计算机中如何存储
UCS-2 vs. UCS-4
UCS-4根据最高位为0的最高字节分成2^7=128个group
每个group再根据次高字节分为256个plane
每个plane根据第3个字节分为256行(rows)
每行包含256个cells
当然同一行的cells只是最后一个字节不同,其余都相同
group0的plane0被称作Basic Multilingual Plane, 即BMP戒者说UCS-4中,高两个字节为0的码位被称作BMP
将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2
在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。
而目前的UCS-4规范中还没有任何字符被分配在BMP之外
存储方式(UTF)UCS Transformation Format
UTF-16
使用变长两/四个字节来表示一个代码点
不UCS-2基本等同
把UCS-2规定的代码点通过Big Endian戒Little Endian方式直接保存下来
UTF-16/UTF-16BE/UTF-16LE
Windows平台下默认的Unicode编码为Little Endian的UTF-16
与ASCII不兼容
UTF-32
用四个字节来表示一个代码点
可以完全表示UCS-4的所有代码点
UTF-32、UTF-32BE、UTF-32LE
非常浪费空间
与ASCII不兼容
UTF-8
目前应用最广泛的一种Unicode编码方案
采用1-4个字节变长
对于ASCII字符的编码使用单字节,兼容ASCII
对于其他字符,则使用2-4个字节来表示
“汉”U+6C49
用3字节模板:1110xxxx 10xxxxxx 10xxxxxx0
6C49二进制:0110 110001 001001
得到:11100110 10110001 10001001,即E6 B1 89
UTF的字节序和BOMByte Order Mark:标记字节顺序戒编码开头字节Charset/encodingEF BB BF UTF-8 FE FF UTF-16/UCS-2, little-endian FF FE UTF-16/UCS-2, big-endian FF FE 00 00 UTF-32/UCS-4 little-endian 00 00 FE FF UTF-32/UCS-4, big-endian
字符编码转换工具
1. windows系统中各种文本编辑器的“另存为”
2. Linux下可以使用iconv
iconv -f utf-8 -t gbk DownloadDirtywordAction
3. 其他方式
乱码使用了错误的字符编码去解码字节流当程序使用特定字符编码解析字节流的时候,一旦遇到无法解析的字节流时,就会用?戒者来替代各种各样的乱码:1. 文件名乱码2. 拷贝乱码3. 控制台乱码4. vi乱码5. mysql乱码… …
文件名乱码
拷贝乱码
控制台乱码
通过安装zhcon 可以在控制台输入和显示中文
big endian和little endian是CPU处理多字节数的不同方式
例如:
“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?
如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian
参考资料
http://just-study.blogbus.com《字符编码》
http://www.imkevinyang.com《关于字符编码,你所需要知道的》
本文原创自无线技术运营空间: http://wireless.qzone.qq.com 及 http://blog.csdn.net/wireless_tech (专注无线技术运营——无线技术(操作系统/数据库/WEB前端/负载均衡/系统容灾/系统安全/短信接入/WAP接入/3G等)、无线业务运营、无线开放平台、统计分析(用户行为分析/数据挖掘)、CP合作,联系我们:1780551083@qq.com)