`

转载:字符集与编码的故事

 
阅读更多
这篇文章写得好,转载一下:

————————————————————————————————————————

很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为"字节"。 再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去。他们看到这样是好的,于是它们就这机器称为"计算机"

开始计算机只在美国用。八位的字节一共可以组合出256(2的8次方)种不同的状态。 他们把其中的编号从0开始的32种状态分别规定了特殊的用途,一但终端、打印机遇上约定好的这些字节被传过来时,就要做一些约定的动作。遇上00x10, 终端就换行,遇上0x07, 终端就向人们嘟嘟叫,例好遇上0x1b, 打印机就打印反白的字,或者终端就用彩色显示字母。他们看到这样很好,于是就把这些0x20以下的字节状态称为"控制码"
  
他们又把所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示,一直编到了第127号,这样计算机就可以用不同字节来存储英语的文字了。大家看到这样,都感觉很好,于是大家都把这个方案叫做 ANSI 的"Ascii"编码(American Standard Code for Information Interchange,美国信息互换标准代码)。当时世界上所有的计算机都用同样的ASCII方案来保存英文文字

后来,就像建造巴比伦塔一样,世界各地的都开始使用计算机,但是很多国家用的不是英文,他们的字母里有许多是ASCII里没有的,为了可以在计算机保存他们的文字,他们决定采用127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到了最后一个状态255。从128到255这一页的字符集被称"扩展字符集"。从此之后,贪婪的人类再没有新的状态可以用了,美帝国主义可能没有想到还有第三世界国家的人们也希望可以用到计算机吧 

等中国人们得到计算机时,已经没有可以利用的字节状态来表示汉字,况且有6000多个常用汉字需要保存呢。但是这难不倒智慧的中国人民,我们不客气地把那些127号之后的奇异符号们直接取消掉, 规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。  中国人民看到这样很不错,于是就把这种汉字方案叫做 "GB2312"。GB2312 是对 ASCII 的中文扩展

但是中国的汉字太多了,我们很快就就发现有许多人的人名没有办法在这里打出来,特别是某些很会麻烦别人的国家领导人。于是我们不得不继续把 GB2312 没有用到的码位找出来老实不客气地用上。 后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 GBK 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。  后来少数民族也要用电脑了,于是我们再扩展,又加了几千个新的少数民族的字,GBK 扩成了 GB18030。从此之后,中华民族的文化就可以在计算机时代中传承了

中国的程序员们看到这一系列汉字编码的标准是好的,于是通称他们叫做 "DBCS"(Double Byte Charecter Set 双字节字符集)。在DBCS系列标准里,最大的特点是两字节长的汉字字符和一字节长的英文字符并存于同一套编码方案里,因此他们写的程序为了支持中文处理,必须要注意字串里的每一个字节的值,如果这个值是大于127的,那么就认为一个双字节字符集里的字符出现了
   
因为当时各个国家都像中国这样搞出一套自己的编码标准,结果互相之间谁也不懂谁的编码,谁也不支持别人的编码,连大陆和台湾这样只相隔了150海里,使用着同一种语言的兄弟地区,也分别采用了不同的 DBCS 编码方案。当时的中国人想让电脑显示汉字,就必须装上一个"汉字系统",专门用来处理汉字的显示、输入的问题,但是那个台湾的愚昧封建人士写的算命程序就必须加装另一套支持 BIG5 编码的什么"倚天汉字系统"才可以用,装错了字符系统,显示就会乱了套!这怎么办?而且世界民族之林中还有那些一时用不上电脑的穷苦人民,他们的文字又怎么办? 真是计算机的巴比伦塔命题啊

正在这时,大天使加百列及时出现了:一个叫 ISO (国际标谁化组织)的国际组织决定着手解决这个问题。他们采用的方法很简单:废了所有的地区性编码方案,重新搞一个包括了地球上所有文化、所有字母和符号的编码!他们打算叫它"Universal Multiple-Octet Coded Character Set",简称 UCS, 俗称 "UNICODE"

UNICODE 开始制订时,计算机的存储器容量极大地发展了,空间再也不成为问题了。于是 ISO 就直接规定必须用两个字节,也就是16位来统一表示所有的字符,对于ascii里的那些"半角"字符,UNICODE 包持其原编码不变,只是将其长度由原来的8位扩展为16位,而其他文化和语言的字符则全部重新统一编码。由于"半角"英文符号只需要用到低8位,所以其高8位永远是0,因此这种大气的方案在保存英文文本时会多浪费一倍的空间
 
从前多种字符集存在时,那些做多语言软件的公司遇上过很大麻烦,他们为了在不同的国家销售同一套软件,就不得不在区域化软件时也加持那个双字节字符集咒语,不仅要处处小心不要搞错,还要把软件中的文字在不同的字符集中转来转去。UNICODE 对于他们来说是一个很好的一揽子解决方案,于是从 Windows NT 开始,MS 趁机把它们的操作系统改了一遍,把所有的核心代码都改成了用 UNICODE 方式工作的版本,从这时开始,WINDOWS 系统终于无需要加装各种本土语言系统,就可以显示全世界上所有文化的字符了

但是,UNICODE 在制订时没有考虑与任何一种现有的编码方案保持兼容,这使得 GBK 与UNICODE 在汉字的内码编排上完全是不一样的,没有一种简单的算术方法可以把文本内容从UNICODE编码和另一种编码进行转换,这种转换必须通过查表来进行

如前所述,UNICODE 是用两个字节来表示为一个字符,他总共可以组合出65535不同的字符,这大概已经可以覆盖世界上所有文化的符号。如果还不够也没有关系,ISO已经准备了UCS-4方案,说简单了就是四个字节来表示一个字符,这样我们就可以组合出21亿个不同的字符出来(最高位有其他用途),这大概可以用到银河联邦成立那一天吧

UNICODE 来到时,一起到来的还有计算机网络的兴起,UNICODE 如何在网络上传输也是一个必须考虑的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF8就是每次8个位传输数据,而UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODE到UTF时并不是直接的对应,而是要过一些算法和规则来转换

受到过网络编程加持的计算机僧侣们都知道,在网络里传递信息时有一个很重要的问题,就是对于数据高低位的解读方式,一些计算机是采用低位先发送的方法,例如我们PC机采用的 INTEL 架构,而另一些是采用高位先发送的方式,在网络中交换数据时,为了核对双方对于高低位的认识是否是一致的,采用了一种很简便的方法,就是在文本流的开始时向对方发送一个标志符。如果之后的文本是高位在位,那就发送"FEFF",反之,则发送"FFFE"。不信你可以用二进制方式打开一个UTF-X格式的文件,看看开头两个字节是不是这两个字节

讲到这里,我们再顺便说说一个很著名的奇怪现象:当你在 windows 的记事本里新建一个文件,输入"联通"两个字之后,保存,关闭,然后再次打开,你会发现这两个字已经消失了,代之的是几个乱码!呵呵,有人说这就是联通之所以拼不过移动的原因
分享到:
评论

相关推荐

    (资料大全加程序)C++ 字符串之间的相互转化 宽字符与多字符集(LPTSTR、LPCSTR、LPCTSTR、LPSTR)

    - `宽字符集----转载 - 游子的博客 - IT博客.mht` 和 `宽字符与多字符集(LPTSTR、LPCSTR、LPCTSTR、LPSTR) - 轻轻浪花 - CSDN博客.mht` 这两个文件可能是博客文章的存档,详细讨论了宽字符集的使用和LPTSTR等相关...

    utf8的编码算法 转载

    在计算机系统中,Unicode字符集提供了一种统一的方式来表示世界上各种语言的字符,包括拉丁字母、希腊字母、汉字、阿拉伯文等。Unicode字符集中的每一个字符都有一个唯一的整数编号,称为Unicode码点。 UTF-8的编码...

    运行vbs脚本报错无效字符、中文乱码的解决方法(编码问题)

    对于包含复杂字符集的脚本,使用Unicode格式可以提供更好的兼容性。 在编写脚本时推荐使用专门的文本编辑器,比如Notepad++。Notepad++是一种功能强大的编辑器,它支持多种编码格式,并且提供了方便的编码转换工具...

    [转载]彻底解决简繁体软件乱码问题

    乱码通常出现在不支持特定字符集或者编码格式的软件上,导致文字无法正常显示,给用户带来了阅读和使用的不便。本文将深入探讨如何彻底解决简繁体软件乱码问题,并提供一个视频教程作为辅助学习资源。 首先,我们...

    转载 纯nasm实现中文操作系统.txt

    在标准ASCII码中无法直接表示中文字符,因此需要使用扩展的字符集或者通过特殊的编码方式来实现中文字符的显示。具体实现方法未在提供的代码片段中体现,但可以推测可能采用了自定义的中文字符集或编码方案。 #### ...

    深入分析 Java I/O 的工作机制(转载)

    10. **字符集编码** Java I/O系统广泛涉及字符编码,如ASCII、UTF-8、GBK等。Charset类提供了字符集的相关操作,InputStreamReader和OutputStreamWriter在创建时需要指定字符集。 总的来说,Java I/O机制是一个...

    解决网页乱码.zip

    charset=UTF-8`,其中`charset`属性定义了内容的字符集。而`request.setCharacterEncoding()`和`response.setCharacterEncoding()`则是设置请求和响应的编码方式,通常用于处理POST请求的数据编码。 ...

    移远M26 AT命令手册

    用户需了解模块支持的字符集,以便在通信中使用正确的字符编码。同时,手册也介绍了硬件流控和软件流控的区别和使用场景。 #### 5. AT命令详解 手册详尽地列出了各种AT命令及其格式和用途。例如,“ATI”命令用于...

    webfilter的教程

    `Filter`可以用于确保所有请求都被正确地解码为UTF-8或其他指定的字符集。通过重写`doFilter`方法,我们可以捕获请求,并使用`HttpServletRequest`的`setCharacterEncoding`方法来设置合适的字符编码,防止乱码问题...

    这计算机组成原理考研大纲(转载).pdf

    本章涵盖了数在机器中的表示方法(如二进制、真值和机器数、BCD编码、字符与字符串),以及定点数和浮点数的运算。这部分知识常出现在选择题中,尤其是数制转换和定点数运算,包括移位运算、加减运算及溢出判断。...

    html 语言 学习札记

    charset=gb2312" />`,这告诉浏览器文档的字符集是GB2312,以确保正确显示非ASCII字符。 样式表在HTML中的应用有两种方式: 1. 页面内嵌法:将CSS直接写在`<head>`标签内的`<style>`标签中,这样可以对当前页面...

    Java字节码(.class文件)格式详解((转载)

    5. 方法表集合:与字段表类似,记录了类的方法信息,包括访问标志、名称索引、描述符索引、属性表集合。其中,属性表可能包含字节码指令。 6. 属性表集合:这部分包含非结构化的信息,如类的注解、方法的异常处理、...

    洪恩在线成语词典小偷程序php版

    6. **UTF-8与GB2312编码**:UTF-8是一种广泛使用的字符编码,而GB2312是中国国家标准的字符集。由于本程序需要在中文环境下显示内容,因此需要将UTF-8编码的文本转换为更符合中文用户习惯的GB2312编码。 7. **...

    42_HTML基礎.pdf

    - meta元素用于描述文档的元数据,例如文档的字符集、页面描述、关键词等。meta元素的用法很灵活,可以通过name和content属性来指定不同的元信息。 - title元素用于指定文档的标题,这个标题会显示在浏览器的标题栏...

    cobaltstrike_release-20210907.7z

    + 使用 sleep_mask 集验证信标是否有足够的代码洞空间。 + 更新 Mimikatz (2.2.0 20210724) + 使用证书/子域信息更新 Cobalt Strike 更新程序 + 添加客户端重连选项 + 通过 NanoHTTPD 发送数据时添加缓冲 + 更新链接...

    springmybatis

    其实还有更简单的方法,而且是更好的方法,使用合理描述参数和SQL语句返回值的接口(比如IUserOperation.class),这样现在就可以至此那个更简单,更安全的代码,没有容易发生的字符串文字和转换的错误.下面是详细...

    CentOS6.8中/英文环境切换教程图解

    2. **查看所有支持的环境**:运行`locale -a`列出所有支持的编码和字符集,然后使用`grep en_US`过滤出与英文相关的选项。注意,这里可能会看到`en_US.utf8`,但在修改时应使用`en_US.UTF-8`的形式,因为系统需要...

    PHP连接数据库实现注册页面的增删改查操作

    在上述内容中,演示了如何用PHP代码连接MySQL数据库,其中使用了`mysql_connect`函数来建立连接,`mysql_select_db`选择特定的数据库,以及`mysql_set_charset`设置字符集为`utf8`以支持中文显示和存储。 接下来,...

    python3.7 使用pymssql往sqlserver插入数据的方法

    除此之外,还可以指定字符集(charset)来确保数据编码的正确性,并且可以设置autocommit参数来决定是否自动提交事务。 在建立连接之后,会得到一个游标对象(cursor),这是用来执行SQL语句的接口。在这个例子中,...

Global site tag (gtag.js) - Google Analytics