今天看到一个面试问题:Unicode 和 UTF-8 有何区别?
我的简单理解就是Unicode 是字符集,而UTF-8是编码集/方式,之前在HTML字符集里总结过相关问题。但是今天搜索后又有一些更深的理解,这里记录下
把这些基础写了出来,是觉得就算是基础有些还是不会,所以总结下。基础很重要,基础越熟练,你走的越快。
【引文】
广义的 Unicode 是一个标准,定义了一个字符集以及一系列的编码规则,即 Unicode 字符集和 UTF-8、UTF-16、UTF-32 等等编码规则。
简单来说:
Unicode 是「字符集」,符号范围是16进制
UTF-8 是「编码规则」,范围是二进制
其中:
字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code Point)
编码规则:将「码位」转换为字节序列的规则(编码/解码 可以理解为 加密/解密 的过程)
也就是说unicode是字符集,而utf8是unicode的一种编码方式
【主体】
我今天用了一个白天的时间把这个问题好好梳理了一遍,来这里做分享。
一.一切的开始-----ASCII
计算机是无法识别字母和符号的,他只能用数字来做处理,那么此时ASCII码孕育而生,所谓ASCII码,就是将英文字母和常用符号用特定的数字去表达。比如:字母A用ASCII编码是十进制的65,二进制的01000001;字符0用ASCII编码是十进制的48,二进制的00110000,注意字符'0'和整数0是不同的;
我们可以这样理解ASCII码,她就是一个字典,是英文世界和计算机世界沟通的通道。这个通道让一开始的沟通变顺畅。就这样计算机和程序员愉快的交流着。可是随着发展问题随之而来。中文和其他世界的也要和计算机沟通,中文和其他的语言的的进入,那ASCII肯定是不够的。
我们知道,一个字母和符号是一个字节,而一个汉字是两个字节。所以在中文输入的时候,ASCII是不能用的。一时间,编码的世界就像是进入了战国,每个地方都在制定自己编码规则。中国制定了GB2312编码,用来把中文编进去。日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里。编码的世界混乱了。
二.分久必合
计算机的实质是交流,和任何人交。所以这个分乱规则肯定是不可以的。大家一商量,把所有的字符写在一个规则下,这样Unicode出生了。Unicode包含我们现在可以用到的所有字符,Unicode也就出一个存下来所有符号的字典,重新担当起计算机世界和人类世界的翻译工作。
到这里我再说一句,对于理解Unicode你将它要理解为字典。我们可以随时把他当做的翻译的依据。但是对于Unicode我们也是编码的。其中一开始编码方式是UCS-2。一般的汉字是两个字节,所以大多的UCS-2用两个字节来表示,但是某些偏僻的汉字和符号用4个字节。可是表示的多也会产生问题。就是我用一个英文字符的时候,我只需要用一个字节就可以存储,那么用Unicode这个字典进行转化的时候。我们知道计算机的内存在以前是很稀缺的资源,所以这种浪费资源的事我们是不会干的。
三.UTF-8由来
我们为了让内存占用更加少,开始用另一种编码方式,基于Unicode让英文字符和符号占有1个字节。此时的汉子是占3~6个字节。所以在英文文档中,用UTF-8是节省空间的。还有一点值得注意,就是UTF-8和ASCII的编码在英文和一些字符的表达上是一样的。所以带来的好处就是,在一些使用ASCII编码的旧的系统和设备上,用UTF-8是可以继续使用的。
所以会有这样的答复:UTF-8是对Unicode编码的一种编码方式
由来原因:节省流量和硬盘
但是:一个汉字在UTF-8编码的情况下可能需要三个字节,使用gbk两个字节就足够了,所以有时候为了节省流量和硬盘,在面对中文世界时,也有使用gbk或者gbk2312编码的
关于进制的介绍,我在文章关于进制里做了总结
【END】
最后分享下别人的答复:
①UTF-8是对Unicode编码的一种编码方式。
原因:节省流量和硬盘
但是:一个汉字在UTF-8编码的情况下可能需要三个字节,使用gbk两个字节就足够了,所以有时候为了节省流量和硬盘,在面对中文世界时,也有使用gbk或者gbk2312编码的
②Unicode就是包含所有字符的字符集,解决了世界各地每个地方所用的编码方式不一样的尴尬,让我们更好沟通。UTF-8就是为了解决Unicode存在内存问题,将Unicode再次编码的一种编码方式
③可以这样来理解:
字符串是由字符构成,字符在计算机硬件中通过二进制形式存储,这种二进制形式就是编码。如果直接使用 “字符串↔️字符↔️二进制表示(编码)” ,会增加不同类型编码之间转换的复杂性。
所以引入了一个抽象层,“字符串↔️字符↔️与存储无关的表示↔️二进制表示(编码)” ,这样,可以用一种与存储无关的形式表示字符,不同的编码之间转换时可以先转换到这个抽象层,然后再转换为其他编码形式。在这里,unicode 就是 “与存储无关的表示”,utf—8 就是 “二进制表示”。
④计算机内只能保存101010等二进制数据,那么页面上显示的字符是如何显示出来的呢?
一:字符集(Charset)
charset = char + set,char 是字符,set是集合,charset就是字符的集合。字符集就是是这个编码方式涵盖了哪些字符,每个字符都有一个数字序号。
二:编码方式(Encoding)
编码方式就是一个字符要怎样编码成二进制字节序,或者反过来怎么解析。也即给你一个数字序号,要编码成几个字节,字节顺序如何,或者其他特殊规则。
三:字形字体(Font)
根据数字序号调用字体存储的字形,就可以在页面上显示出来了。所以一个字符要显示出来,要显示成什么样子要看字体文件。
综上所述,Unicode 只是字符集,而没有编码方式。UTF-8 是一种 Unicode 字符集的编码方式,其他还有 UTF-16,UTF-32 等。而有了字符集以及编码方式,如果系统字体是没有这个字符,也是显示不出来的。
【拓展】
(一)字符串与编码
计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295。
由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。
但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。
你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。
现在,捋一捋ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。
字母A用ASCII编码是十进制的65,二进制的01000001;
字符0用ASCII编码是十进制的48,二进制的00110000,注意字符'0'和整数0是不同的;
汉字中已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101。
你可以猜测,如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001。
新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。
所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:
A | 01000001 | 00000000 01000001 | 01000001 |
中 | x | 01001110 00101101 | 11100100 10111000 10101101 |
从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。
搞清楚了ASCII、Unicode和UTF-8的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件:
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器:
所以你看到很多网页的源码上会有类似<meta charset="UTF-8" />的信息,表示该网页正是用的UTF-8编码。
(二)字符编码中ASCII、Unicode和UTF-8的区别
1. ASCII码
我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。
上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。
ASCII码一共规定了128个字符的编码,比如空格"SPACE"是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。
2、非ASCII编码
英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。比如,在法语中,字母上方有注音符号,它就无法用ASCII码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。
但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0--127表示的符号是一样的,不一样的只是128--255的这一段。
至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示256x256=65536个符号。
中文编码的问题需要专文讨论,这篇笔记不涉及。这里只指出,虽然都是用多个字节表示一个符号,但是GB类的汉字编码与后文的Unicode和UTF-8是毫无关系的。
3.Unicode
世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。
可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是Unicode,就像它的名字都表示的,这是一种所有符号的编码。
Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字"严"。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表。
4. Unicode的问题
需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
比如,汉字"严"的unicode是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。
这里就有两个严重的问题
第一个问题是,如何才能区别Unicode和ASCII?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?
第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。
它们造成的结果是:1)出现了Unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示Unicode。2)Unicode在很长一段时间内无法推广,直到互联网的出现。
5.UTF-8
互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:
(1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
(2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
下表总结了编码规则,字母x表示可用编码的位。
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
下面,还是以汉字"严"为例,演示如何实现UTF-8编码。
已知"严"的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此"严"的UTF-8编码需要三个字节,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。然后,从"严"的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,"严"的UTF-8编码是"11100100 10111000 10100101",转换成十六进制就是E4B8A5。
.
相关推荐
"Unicode编码和双向算法(bidi)详解" 本文对 Unicode 编码和双向算法(bidi)进行了详细的讲解,涵盖了 Unicode 编码的基本概念、UTF-8 和 UTF-16 编码方式、双向算法的基本规则和实现细节等内容。 Unicode 编码是...
Unicode 编码方式详解 Unicode 编码方式是计算机程序或数据文件中文本存储和表示的一种方式。文本是由字符组成的,字符可以是字母、数字、句点、连字号、标点符号和数学符号等。为了在计算机中存储和表示这些字符,...
《中文Unicode编码表详解》 Unicode编码,全称为统一码或万国码,是一种在计算机上表示文本的标准化方式,旨在解决全球不同语言字符的表示问题。中文Unicode编码表是Unicode标准的一部分,它包含了所有中文字符的...
本文将基于“汉字unicode码.txt”文件提供的信息,深入探讨汉字Unicode编码的相关知识点。 #### 二、基础知识 1. **Unicode简介**: - Unicode是一种多字节字符编码标准,旨在为所有语言提供统一且兼容的编码方案...
### 维吾尔文Unicode编码表详解 #### 标题:维吾尔文Unicode编码表 **维吾尔文Unicode编码表**是针对现代维吾尔文中使用的字母、标点符号等字符制定的一种标准化编码方案。该编码表遵循Unicode国际标准,确保了...
根据提供的文件内容,我们了解到该文件包含了一段特殊的Unicode编码表示例,范围为`4e00-9fa5`,这部分是Unicode标准中用于表示常用汉字的部分。 ##### 字符范围解析 - **起始码位**:`4e00` - 表示该范围内的第...
### Unicode编码详解 #### 一、引言 随着信息技术的发展,全球化的进程加快,不同语言间的交流变得越来越频繁。为了确保各种文字能够在全球范围内被准确地处理和显示,Unicode编码应运而生。本文旨在深入探讨...
**Unicode编码源代码详解** Unicode编码是一种全球统一的字符编码标准,旨在表示世界上几乎所有的文字系统,包括拉丁字母、希腊字母、汉字、日语假名等。它为每个字符分配了一个唯一的数字,称为码点,使得不同语言...
《汉字与Unicode编码详解及其转换应用》 在数字化的世界里,字符编码扮演着至关重要的角色,尤其是对于拥有丰富字符集的汉字来说。Unicode编码体系,作为全球通用的字符编码标准,为包括汉字在内的各种语言提供了...
### Unicode编码表知识点详解 #### 一、Unicode简介与背景 **Unicode**是一种国际标准的字符编码方案,旨在为世界上所有书写系统提供统一且唯一的数字表示。它解决了不同语言文字在计算机中的编码问题,使多语言...
假设我们要将一段文本从GB2312编码转换为Unicode编码,首先需要准备一个完整的映射表,该映射表包含了所有GB2312编码与Unicode编码之间的对应关系。接着,可以编写一个程序来读取这段文本,并按照上述流程进行转换。...
本文将基于给定的文件内容,深入探讨部分常用汉字的Unicode编码与对应的拼音,帮助理解汉字编码的基础知识。 #### Unicode与汉字的关系 Unicode编码是国际上广泛采用的字符编码方案之一,旨在解决多语言环境下的...
**Unicode编码详解** Unicode编码采用了一种二进制编码方式,将每个字符与一个唯一的数字(码点)关联。基本多文种平面(BMP)是Unicode的第一部分,包含了大部分常用字符,码点范围从U+0000到U+FFFF。对于不在BMP...
字符编码详解 字符编码是计算机科学中的一种基础概念,它是指将文字、符号等字符转换为计算机可以识别的二进制代码的过程。常用的字符编码有 ASCII、GB2312、GBK、GB18030 等。 1. ASCII 编码 ASCII 编码是一种 7...
2. **编码到Unicode的映射**: 计算机操作系统(如Windows)需要将这些编码数据映射到内部使用的Unicode编码,以便统一处理来自不同编码系统的文字。 3. **字体渲染**: 映射完成后,系统根据Unicode值在字体文件中...
本文将深入解析几种常见的编码标准,包括UCS、BMP、Unicode以及UTF-8。 首先,UCS(Universal Character Set)是一种多字节字符集,由ISO/IEC 10646-1标准定义,目的是涵盖全球各种语言的书写字符。UCS有UCS-4和UCS...
**排序编码表与Unicode编码详解** 在信息技术领域,字符编码是一种至关重要的标准,它使得计算机能够识别、存储和处理各种语言的文字。Unicode是目前最广泛使用的字符编码标准,旨在为世界上几乎所有的文字提供一个...