常用编码学习

常用编码

在计算机世界,所有信息都是用二进制存储。每一个二进制有0和1两种状态。

所以8个二进制就可以组合成256种状态,也就是一个字节。

也就是说,一个字节可以用来表示256种不同的状态,每一个状态对应一个符号,也就是256个符号,从00000000—11111111。

ASCII码

一共规定了128个字符的编码,包含大小写字母、数字、还有空格等一些常用符号,这128个符号中有32个不能打印出来的控制符号。只占用了一个字节的后面7位,也就是最前面一位都是0.

大写字母A是65,也就是二进制的01000001。

空格是32,也就是二进制的00100000。

非ASCII编码

上面讲的ASCII编码规定的128个字符,对英语来说足够用了,但是用来表示其他语言,128个符号不够用。例如,法语字母上面有注音符号,它就无法用ASCII码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。

比如,法语的é的编码为130,二进制位10000010,这样以来欧洲国家可以使用8个二进制的所有组合,也就是最多256个符号。

但是,这也有问题,130在法语编码中表示é,而在希伯来语编码中却代表字母Gimel(?),在俄语编码中又代表另一个符号。但是不管怎样,所有这些编码方式中,0—127表示的符号是不一样的,不一样的只是128—255的这一段。

至于亚洲国家的文字,额….汉字就10W+,256种符号肯定不够,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是GB2312,使用256个字节表示一个汉字,所以理论上最多表示256*256=65536个符号。

当然,世界上的编码方式有很多,不止上面提到的这些。

Unicode

世界上存在着多种编码方式,同一个二进制数字可以被解释不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

Unicode是一种把世界上所有符号都纳入其中,每一个符号都给予了一个独一无二的编码,那么乱码问题就会消失。

Unicode是一个很大的集合,现在的规模可以容纳100多万个符号,每个符号的编码都不一样,比如:

U+0639表示阿拉伯字母Ain。

U+0041表示英语的大写字母A

U+4E25 表示汉字严

Unicode的问题

Unicode只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

例如:汉字转化为二进制是100111000100101,足足有15位,也就是最少需要两个字节,甚至有更大的符号,需要3个字节或者4个字节,甚至更多。

这就有了两个严重的问题:

1.如何区分Unicode和ASCII,计算机怎么知道三个字节表示一个符号,而不是表示三个符号呢?

2.我们已经知道英文字母只用一个字节表示就足够了,如果Unicode同一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必须有2—3个字节是0,这对于数据存储来说是极大的浪费,文本文件的大小因此会打出2—3倍,这是无法接受的。

UTF-8闪亮登场

UTF-8Unicode的一种实现方式,其他实现方式还有UTF-16(字符用2—4个字节表示),UTF-32(字符用四个字节表示),不过其他的在互联网上基本不用,UTF-8就是为了统一编码方式产生的,也是互联网上使用最广的一种Unicode的实现方式。

UTF-8的最大特点,就是它是一种边长的编码方式,可以使用1—4个字节来表示一个符号,根据不同的符号而变化字节长度。

它的规则很简单,只有两条:

对于单字节的符号,字节的第一位为0,后面7位为这个符号的Unicode码。因此,对于英文字母,UTF-8和ASCII码是相同的。

对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律为10。

汉字的Unicode是4E25(100111000100101),需要用三个字节存储,根据上面的规则,即格式为:

1110xxxx 10xxxxxx 10xxxxxx

记住,二进制是从后往前存储的,读也是从后往前读的,所以我们先填充第三个字节,从二进制的后面读取,填充完后变成了:

1110xxxx 10xxxxxx 10100101

再根据同样规则填充第二个字节,填充完后变成了:

1110xxxx 10111000 10100101

最后填充最后一个字节:

1110x100 10111000 10100101

不对啊,怎么少了一个字节?没事,少了的用0补位:

11100100 10111000 10100101

Unicode与UTF-8的转换

这两种编码的转换可以通过程序实现,在Windows平台下,最简单的方法是,通过记事本另存为:

ACSI就是ACSII,是Windows英文系统的默认的编码格式,但是对于Windows简体中文版默认就是GB2312,针对繁体中文版默认就是Big5。

而现显示的Unicode都是使用UCS-2编码方式存储的Unicode字节,只不过默认是little endian格式,而另一个选项是Unicode big endian格式。

Unicode little endianUnicode big endian的转换:

简单举个例子,UCS-2格式可以存储Unicode码。汉字的Unicode码为4E25,需要用两个字节存储,一个字节是4E,另一个是25。4E在前,25在后就是Big endian(从前往后),25在前,4E在后,就是Little endian(从后往前)。

那计算机怎么知道某一个文件到底采用哪一种方式编码呢?

Unicode规范定义,每一个文件最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做 “zero width no-break space” ,用FEFF表示,正好是两个字节。

如果一个文本文件的头两个字节是FE FF,表示是Big endian方式,如果头两个字节是FF FE,表示是Little endian方式。

本文大部分来自阮一峰大神的个人博客:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

原文地址:https://www.cnblogs.com/Fill/p/9581585.html

时间: 2024-10-24 08:07:39

常用编码学习的相关文章

html常用标签学习

1.html常用标签学习:1.1.<em>和<strong>标签主要是用来做强调用的,其中<em>是让文字变成斜体,而<strong>把文字进行加粗显示.1.2.<span>标签是没有语义的,它的作用就是为了设置单独的样式用的.1.3.<q>标签是做文本引用时候用的,需要引用的文本不需要加双引号,浏览器会自动为<q>标签加上引号.<blockquote>标签是对长文本进行引用,引用短文本比如一句话就用<q

compass General 常用api学习[Sass和compass学习笔记]

compass 中一些常用api 包括一些浏览器hack @import "compass/utilities/general" Clearfix Clearfix 是用来清除浮动 float 造成的内容问题,以前用clear 方法可以解决,通过查看Clearfix 的源码发现对与高版本的浏览器其实已经可以不用了 ? 1 2 3 4 @mixin clearfix {   overflow: hidden;   @include has-layout; } 用overflow 就可以了

mysql常用命令学习

1.\c取消当前准备执行的sql语句. mysql> select user,host,password from mysql.user;\c +--------+-----------+----------+ | user   | host      | password | +--------+-----------+----------+ | root   | localhost |          | | root   | mytest2   |          | | root  

linux 几个不常用命令学习 之 cal 命令

看了极客里面的文章:一些实用但不为人知的unix命令 文章参考:http://blog.jobbole.com/66590/ 准备好好学习下这些命令,成为Linux高手 这次学习显示日历命令:cal #显示日历,默认格式 $ cal 五月 2014 日 一 二 三 四 五 六 1  2  3 4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #默认日历显示是从星期天作为第一天,你也

python之路,Day24 常用设计模式学习

python之路,Day24 常用设计模式学习 本节内容 设计模式介绍 设计模式分类 设计模式6大原则 1.设计模式介绍 设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一

Day5 - Python基础5 常用模块学习

Python 之路 Day5 - 常用模块学习 本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configparser hashlib subprocess logging模块 re正则表达式 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,

Python之路,Day21 - 常用算法学习

Python之路,Day21 - 常用算法学习 本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出.如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题.不同的算法可能用不同的时间.空间或效率来完成同样的任务.一个算法的优劣可以用空间复杂度与时间复杂度来衡量. 一个算

C# 常用接口学习 IEnumerable&lt;T&gt;

C# 常用接口学习 IEnumerable<T> 作者:乌龙哈里 时间:2015-10-24平台:Window7 64bit,Visual Studio Community 2015 本文参考: MSDN IEnumerable<T> Interface MS DotNet 源代码 你曾实现过二叉树吗--匠心十年 你可能不知道的陷阱, IEnumerable接口--沙漠之鹰 本文章节: 正文: 本文是作者摸索学习.Net的过程,逐步进行,比较繁琐,是作者本人用来帮助记忆的博文. 我

Linux的几个概念,常用命令学习

Linux的几个概念,常用命令学习---------------------------------设备名装载点// 通过装载点访问设备---------------------------------根目录:cd /主目录:cd ~ // 不同的用户有不同的主目录,但拥有相同的根目录----------------------------------点文件:以点开头的文件或目录,可以作为隐藏目录ls 不显示ls -a 显示--------------------------------标准子目