美文网首页程序员
对字符编码的理解

对字符编码的理解

作者: 赵默阳 | 来源:发表于2018-05-17 04:53 被阅读91次

写在前面:雨夜难眠,就起来学习了一下字符编码的知识。感谢大神们写的博客,参考博客链接已经附在文章末尾。用了几个小时简单的理解了一下,有理解不对的地方,还请大家指教。时间有限也没太过深入学习,还请大家见谅。有理解更深刻的朋友,多多指教啊。

计算机只能够识别0和1,但是随着计算机和计算机语言的发展,人们已经可以使用接近人类语言的计算机语言和人类的语言与计算机交互,但是在计算机认识的还是0和1。于是就出现了编码和解码。

编码就是将 人类语言字符和计算机语言字符  转为  计算机认识的 0和1; 

解码就是将  0和1   转为  人类语言字符和计算机语言字符  。

字符编码

编码和解码所依据的就是字符编码。在字符编码表中,字符集中的字符和字符编码是 一 一 映射,一 一 对应的。

字符编码的发展史

1)字符编码前身

在最初,是没有统一的字符编码的。每个计算机制造商都有自己表示字符的编码和解码方式。但是这样使得计算机之间的数据交换特别麻烦。

最终,计算机制造商们一起制定了一个统一的标准。于是就出现了 ASCII 码。

2)ASCII 码

在 ASCII 码表中,规定一个字符占用一个字节,即占用8位。但是厂商们定义了最低的7位来表示字符,并且制作了字符集与 ASCII码 一 一 映射的 ASCII 码表。

因为只使用了低 7位,所以可表示 000 000 到 111 1111 即十进制 0 - 127 个字符。


image.png



这127个字符中,已经包含了大小写英文字符和一些特殊字符。但这主要是对英文字母和英文字符的编码。其他国家为了表示自己国家的语言字符和特殊字符,于是,加上最高位来定义自己的语言字符。即 使用 1000 0000 - 1111 1111 这个区间即 128 - 255 来表示自己国家语言字符。例如,144在阿拉伯人的ASCII码中是گ,而在俄罗斯的ASCII码中是ђ。即使在美国,对于未使用区域也有各种各样的利用。IBM PC就出现了“OEM 字体”或”扩展ASCII码”,为用户提供漂亮的图形文字来绘制文本框并支持一些欧洲字符,例如英镑(£)符号。


image.png

因此,ASCII码实现了 0 - 127个字符的编码统一,而128 - 255 区间的字符,还是比较混乱。

3)ISO-8859-1

为了解决 ASCII码高位混乱的问题,出现了 ISO-8859-1 编码。

这套编码规则由ISO组织制定。ISO-8859-1是在 ASCII 码基础上又制定了一些标准用来扩展ASCII编码,ISO-8859-1编码也是单字节编码,使用了最高位8位,因此最多能够表示256个字符。


image.png



Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。

4)DBCS双字节编码

虽然ISO-8859-1解决了高位混乱问题,但是在亚洲面临更大的问题,亚洲语言有更多的字符和字形需要被存储,一个字节已经不够用了。所以在亚洲开始使用两个字节来存储字符,这被称作DBCS(双字节编码方案)。

双字节编码在每个国家都发展了自己的编码表。为了与世界其他国家语言的计算机进行数据交互或者兼容其他国家软件,几乎所有的双字节编码表都支持 ASCII 码。

虽然兼容了 ASCII 码表,但不同国家的 DBCS码表不一,为了交互,于是有了 内码表的概念。即遇到不同国家的语言,就对应使用一个不同国家的内码表。

内码表虽然解决了 DBCS双字节编码 混乱的问题,但是解决方式并不简洁,操作也不方便。

DBCS编码又称为 ANSI编码。

下面重点介绍中国的 DBSC双字节编码表:

① 中国大陆的 GB2312 ,GBK  和 GB 18030

I.  GB2312

1981年5月1日开始实施的一套国家标准,标准号是GB 2312—1980。GB2312主要支持了中文简体。

GB2312是双字节编码, GB2312其对所收录字符进行了"分区"处理,其中高字节表示区,低字节表示位,这种表示方式也称为区位码。

01-09区为特殊符号。
16-55区为一级汉字,按拼音排序。
56-87区为二级汉字,按部首/笔画排序。
10-15区及88-94区则未有编码。

至于怎么分区位,暂时没有研究,后续有空再看吧。

II.  GBK

1995年12月15日国家技术监督局标准化司、电子工业部科技与质量监督司发布了GBK。

GBK 向下与 GB 2312 编码兼容,向上支持 ISO 10646.1国际标准,是前者向后者过渡过程中的一个承上启下的产物。

GBK编码,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案。支持简繁体。


III.  GB 18030

基于 GBK,支持简繁体,日韩文字和字符


② 中国台湾和香港的 BIG5

大五码是由资策会于1984年策划制定。

大五码(Big5),是通行于台湾、香港地区的一个繁体字编码方案。

5)Unicode的世界

最终,美国人意识到他们应该提出一种标准方案来展示世界上所有语言中的所有字符,以便缓解程序员的痛苦和避免字符编码引发的种种麻烦。出于这个目的,Unicode诞生了。

特别注意,unicode只是指明了字符与其对应的码点,并没有指定如何存储。至于Unicode如何存储,主要有两种方案:UCS和UTF。

①UTF

I.  utf-8

utf-8 实现了对ASCII码的向后兼容,以保证Unicode可以被大众接受。

在UTF-8中,0-127号的字符用1个字节来表示,使用和US-ASCII相同的编码。这意味着1980年代写的文档用UTF-8打开一点问题都没有。只有128号及以上的字符才用2个,3个或者4个字节来表示。因此,UTF-8被称作可变长度编码。

II. utf-16

utf-16使用2个或者4个字节来存储字符。

但是UTF-16可能会浪费存储空间,如英文字符可能一个字节就可以表示,两个字节就浪费了空间。

utf-16又分为低字节序和高字节序。低字节序和高字节序只是一个关于在内存中存储和读取一段字节(被称作words)的约定。这意味着当你让计算机用UTF-16把字母A(占两个字节)存在内存中时,使用哪种字节序方案决定了你把第一个字节放在第二个字节的前面还是后面。字节序方案只是一个微处理器架构设计者的偏好问题,例如,Intel使用低字节序,Motorola使用高字节序。

字节顺序标记(BOM):如果你经常要在高低字节序的系统间转换文档,并且希望区分字节序,还有一种奇怪的约定,被称作BOM。BOM是一个设计得很巧妙的字符,用来放在文档的开头告诉阅读器该文档的字节序。在UTF-16中,它是通过在第一个字节放置FE FF来实现的。在不同字节序的文档中,它会被显示成FF FE或者FE FF,清楚的把这篇文档的字节序告诉了解释器。

②UCS

I.  UCS-2

UCS-2是定长字节的,固定使用2个字节进行编码,从0000(十六进制)- FFFF(十六进制)的码位范围,对应第一个Unicode平面。采用BOM(Byte Order Mark)机制,该机制作用如下:1. 确定字节流采用的是大端序还是小端序。2. 确定字节流的Unicode编码方案。

II.  UCS-4

UCS-4是定长字节的,固定使用4个字节进行编码。也采用了BOM机制。

字符编码在计算机程序中的应用

上面了解了字符编码的发展史,我们知道在计算机程序中,只要不使用0和1机器语言,就必然存在编码与解码。因此在每个计算机程序中,只要不是使用0和1机器语言,就必须要指定编码格式。

1)示例1 :使用文本文件或者word等文件

我们使用文本文件或者word等文件的时候,只有我们知道指定了编码格式去编写或使用文本编辑器默认编码格式,我们才能正确的编码与解码文件。

当然,我们也可以使用与文本编码格式兼容的格式。但是一定要确定文件的编码格式。

2)示例2:浏览器

当我们使用了Content-Type或者meta charset标签来显式指定文档的编码,浏览器就能正确解析代码。如果我们没有指定,浏览器就会猜测字符编码格式,因此在渲染文档的时候容易出现乱码。

3)示例3:javac 编译器 及eclipse等第三方集成编译器 与 JVM

首先先看一个图


image.png

I. java源文件编写的编码格式

我们采用不同的工具写java文件的时候,可以指定不同的编码格式。如eclipse notepad 都可以指定编码格式。这是 .java文件的编码格式。

II. javac等编译工具的编码格式

当我们使用javac编译工具,把.java文件编译成class文件的时候。如果我们没有指定javac的编码格式,javac首先获得操作系统默认采用的编码格式。如,Windows 7平台默认为GBK,简体中文操作系统Windows XP、Windows 2000简体中文的缺省编码是GB18030,Linux平台默认为UTF-8

a.  在我们使用javac 编译文件的时候,可以指定javac的编码格式,cmd命令为:

javac -encoding 字符编码格式  Java源文件名.java

b.  eclipse是自动编译的,所以直接设置编码格式,java源文件与class文件都会使用此编码格式。

windows ---> Preferences --->General ---> Workspace  找到 Text file  encoding  设置其编码格式。

III. JVM运行class文件的编码格式

JVM是使用unicode编码格式,确定是 utf-16编码格式。因此,不管 class文件编码格式是什么类型,在 jvm虚拟机内,都会转为 utf-16 .

4)示例4:java语言中的char类型

java语言实现的字符编码格式为 unicode,即utf-16。char类型是使用 2个字节的 utf-16 来实现的。

但是utf-16中,有些字符是占用2个字节,可以整好占用一个char类型。有些字符占用的是4个字节,这些字符一个char类型是表示不了的。因此,char类型只是实现大部分占用2个字节的utf-16字符。占用4个字节的utf-16的字符会出现乱码。因此,char类型要慎用。

参考博客

学点编码知识又不会死:Unicode的流言终结者和编码大揭秘 http://www.freebuf.com/articles/web/25623.html

计算机字符编码详解——从理论到实践 https://blog.csdn.net/xuejianhui/article/details/52650825

[知乎]java编译器编码和JVM编码问题? https://www.zhihu.com/question/30977092

相关文章

  • 对字符编码的理解

    写在前面:雨夜难眠,就起来学习了一下字符编码的知识。感谢大神们写的博客,参考博客链接已经附在文章末尾。用了几个小时...

  • 深入理解Emoji(三) —— Emoji详解

    深入理解Emoji(一) —— 字符集,字符集编码深入理解Emoji(二) —— 字节序和BOM Emoji字符是...

  • 字符串

    1.字符的编码 Python中的字符采用的是Unicode编码 1.什么是编码 :数字和字符是一一对应的,其中字符...

  • [转]【字符编码】彻底理解字符编码

    一、前言 在解决昨天的问题时,又引出了很多新的问题,如为什么要进行编码,这些编码的关系如何,如ASCII,IOS-...

  • day4-字符串

    1.字符编码 python中的字符采用的是Unicode编码 什么是编码将字符与数字一一对应,其中字符对应的数字就...

  • 理解字符编码

    什么是字符编码 我们知道编程就是我们人类给计算机发送指令让计算机进行计算,先抛开我们怎样给计算机发指令这个问题不说...

  • Python基础(二)-字符串和编码

    字符串和编码 字符编码 字符编码也称字集码,是把字符集中的字符编码为指定集合中某一对象,以便文本在计算机中存储和通...

  • escape、encodeURI和encodeURICompon

    escape对字符串(string)编码,另外两种对url进行编码。 escape 这几个字符不会被编码:ASCI...

  • 不同的编码与编码规则

    推荐文章:网页编码就是那点事Unicode 和 UTF-8 有何区别? 编码 个人理解: URL编码实际是将字符的...

  • 什么是编码格式?

    摘要: 字符编码(英语:Character encoding)也称字集码,是把字符集中的字符编码为指定集合中某一对...

网友评论

    本文标题:对字符编码的理解

    本文链接:https://www.haomeiwen.com/subject/jeyvdftx.html