背景概述

在我们的日常工作生活中一定碰到过下面的情况:
场景1:安装完某个软件后,看到的安装程序变成类似这样的一组字符” µç×ÓË°Îñ¾ÖÖ¤ÊéÇý¶¯¼°·þÎñƽ̨”图1所示的样子;
图 1. 安装程序中的乱码
场景2:打开一个文档发现里面的内容全面是问号??????如图2所示;
图 2. 带有问号的乱码
场景3:打开某个网页,却显示成:如"бЇЯАзЪСЯ"、"�????????"?等等;
场景4:打开某个文档后,出现 。
上面例子中看到的就是困扰着我们的乱码。这篇文章基于项目实践,分别从普通用户和编程角度总结了常见的乱码种类,产生原因以及如何解决这些乱码问题。在分析乱码原因和解决办法之前,首先阐述一下和乱码相关的术语。
编码解码概述
我们都知道计算机不能直接存储字母,数字,图片,符号等,计算机能处理和工作的唯一单位是“比特位(bytes)”,一个比特位通常只有0和1,是(yes)和否(no),真(true)或者假(false)等等我们喜欢的称呼。利用比特位序列来代表字母,数字,图片,符号等,我们就需要一个存储规则,不同的比特序列代表不同的字符,这就是所谓的“编码”。反之,将存储在计算机中的比特位序列(或者叫二进制序列)解析显示出来成对应的字母,数字,图片和符号,称为"解码",如同密码学中的加密和解密,下面将详细解释编码解码过程中涉及到的一些术语:
字符集合(Character set):是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等,简单理解就是一个字库,与计算机以及编码无关。
字符编码集(Coded character set):是一组字符对应的编码(即数字),为字符集合中的每一个字符给予一个数字,如Unicode为每一个字符分配一个唯一的码点与之一一对应。
字符编码(Character Encoding):简单理解就是一个映射关系,将字符集对应的码点映射为一个个二进制序列,从而使得计算机可以存储和处理。常见的编码方式有ASCII编码、ISO-8859-1(不支持中文)、GBK、GB2312(中国编码,支持中文)、UTF-8等等,详情见表1。
字符集(Charset):包括编码字符集和字符编码,如ASCII字符集、ISO-8859-X、GB2312字符集(简中)、BIG5字符集(繁中)、GB18030字符集、Shift-JIS等,即下文中提到的字符集。
表1. 常见字符集和对应编码方式
字符集 |
编码 |
详解 |
ASCII |
ASCII编码 |
ASCII字符集:主要包括控制字符(回车键、退格、换行键等);可显示字符(英文大小写字符、阿拉伯数字和西文符号。 ASCII编码:用一个字节的低 7 位表示,0~31 是控制字符如换行回车删除等;32~126 是打印字符;ASCII的最大缺点是只能解决了部份西欧语言的显示问题,但对更多其他语言依然无能为力。 |
ISO-8859-X (常用的ISO-8859-1) |
ISO-8859-1编码 |
ISO-8859-X 字符集:扩展的ASCII字符集,包括 ISO-8859-1 ~ ISO-8859-15,涵盖了大多数西欧语言字符和希腊语。 ISO-8859-1编码:用8位表示一个字符,总共能表示 256 个字符,但还是单字节编码,不能对双字节如中日韩等进行编码。 |
ISO-8859-2编码 |
||
… |
||
ISO-8859-15编码 |
||
GBXXXX |
GB2312编码 |
它的全称是《信息交换用汉字编码字符集 基本集》,它是双字节编码,每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。 总的编码范围是 A1-F7,其中从 A1-A9 是符号区,总共包含 682 个符号,从 B0-F7 是汉字区,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。对于人名、古汉语等方面出现的罕用字,GB2312不能处理,这导致了后来GBK及GB 18030汉字字符集的出现。 |
GBK编码 |
全称叫《汉字内码扩展规范》,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。 |
|
GB18030编码 |
GB18030-2005《信息技术中文编码字符集》 |