Unicode 和 UTF-8 是什么关系?

绝大多数程序员都听说过 Unicode 和 UTF-8,但是清楚它们之间关系的人就不多了,关于这个问题,与其苍白的陈述它们的概念,不如举例子说明来得自然。

我前些天碰到一个需求:随机生成几个汉字。原本我便对编码之类的问题发怵,所以完全搞不清楚状况,无奈之下我便上网搜索了一个 PHP 版本的实现:


  1. <?php
  2. $zh = '';
  3. for($i = 0; $i < 3; $i++) {
  4. $zh .= '&#'. rand(19968, 40869) . ';';
  5. }
  6. echo mb_convert_encoding($zh, 'UTF-8', 'HTML-ENTITIES');
  7. ?>

不过代码里的「19968」和「40869」是什么玩意?这又牵扯到 Unicode code points,为了更好的说明问题,我们需要把如上十进制转换成十六进制:

shell> php -r 'echo dechex(19968);'
4e00

shell> php -r 'echo dechex(40908);'
9fcc

在 Unicode 官方网站,我们能查到 Unihan Grid Index,其中 CJK Unified Ideographs 部分包含了大部分的汉字,其 code points 恰恰是从 U+4E00 到 U+9FCC!

单单上面一个例子还不足以说明问题,下面我们挑选一个「」字深入说明一下:

Unicode

因为我们编码是 UTF-8,所以就先看看「博」字的 UTF-8 编码是什么:


  1. <?php
  2. $string = "博";
  3. for ($i = 0; $i < strlen($string); $i++) {
  4. echo dechex(ord($string[$i]));
  5. }
  6. ?>

代码看上去有点冗长,实际上利用 pack/unpack 函数可以很简单的实现类似的逻辑:

shell> php -r 'var_dump(unpack("H6", "博"));'
array(1) {
  ["codes"]=>
  string(6) "e58d9a"
}

于是乎「博」字的 UTF-8 编码是「e58d9a」,再看怎么得到 unicode code point:

shell> php -r 'echo base_convert("e58d9a", 16, 2);'
11100101 10001101 10011010

如上拿到了「博」字的二进制表示,实际上其 unicode code point 就隐藏在这里。通常汉字用 UTF-8 表示时是三个字节,格式为「1110XXXX 10XXXXXX 10XXXXXX」,除掉标志位,把剩余对应位置上的数据抽取出来连接在一起,就得到了 Unicode code point,也就是「0101 001101 011010」,剩下的就简单了,把它从二进制转换成十六进制即可:

shell> php -r 'echo base_convert("0101001101011010", 2, 16);'
535a

需要说明的是,如果你仅仅看「博」字,会发现其 Unicode code point 和 UTF-16 是一样的,很容易据此认为它们是等同的概念,实际上这个结论仅仅在双字节(UCS-2)时才是成立的,一旦大于两个字节,就不成立了,有兴趣的可以参考相应的例子

到底 Unicode 和 UTF-8 是什么关系?一句话:Unicode 是字符集;UTF-8 是编码

本文来自合作伙伴“Linux中国”,原文发布日期:2015-10-14

时间: 2024-09-04 15:16:12

Unicode 和 UTF-8 是什么关系?的相关文章

python的unicode处理关系

本文主要参考网上文章 Python Unicode Objects之前在编码上绕过些弯路,经常碰到illegal ASCII character一类的问题,就在这儿用图捋一下.unicode编码与其他编码的关系: python对于unicode处理的流程如下:

ANSI、UNICODE、UTF-8、GB2312、GBK、DBCS、UCS的区别和由来。

科普一下,自己也学习一下~~~~~       一直对字符的各种编码方式懵懵懂懂,什么ANSI.UNICODE.UTF-8.GB2312.GBK.DBCS.UCS--是不是看的很晕,假如您细细的阅读本文你一定可以清晰的理解他们.Let's go!              很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为"字节".     再后来,他们又做了一些可以处理这些字节的机器,机器开动了,

unicode ansi utf-8 unicode_big_endian编码的区别

随便说说字符集和编码  快下班时,爱问问题的小朋友Nico又问了一个问题:  "sqlserver里面有char和nchar,那个n据说是指unicode的数据,这个是什么意思."  并不是所有简单的问题都很容易回答,就像这个问题一样.于是我答应专门写一篇BLOG来从头讲讲编码的故事.那么就让我们找个草堆坐下,先抽口烟,看看夜晚天空上的银河,然后想一想要从哪里开始讲起.嗯,也许这样开始比较好--  很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的

java实现十六进制字符unicode与中英文转换示例_java

关于unicode和utf的关系,可以简单的记忆:Unicode是一个编码组织.一个编码规范.在java中指utf-16:utf是Unicode编码的translation转换格式,以便于很好地在网络中传递.在存储媒介汇总保存,于是utf存在多种格式,如8.16.32,而关联le.te的区别,Unicode编码格式才会有以下过程中的10种. 复制代码 代码如下: public static void main(String[] args) throws UnsupportedEncodingEx

支持UNICODE/UTF8/ANSI之间的转换的类

ZUtf8_16.h文件: //---------------------------------------------------------------------------#ifndef ZUtf8_16H#define ZUtf8_16H//---------------------------------------------------------------------------/* 支持UNICODE,UNICODE BE ,UTF8,ASCII之间的转换的类. 日期:2

什么是Unicode,什么是UTF-8_CSS/HTML

一直在编码方面要求不是很高,所以对Unicode和UTF-8也不甚了解. 最近偶然翻到一篇UTF-8的文章,感觉解释的非常繁杂,因此才想到重新写一篇简单易懂一点的. 首先说明一下现在常用的一些编码方案: 1.在中国,大陆最常用的就是GBK18030编码,除此之外还有GBK,GB2312,这几个编码的关系是这样的. 最早制定的汉字编码是GB2312,包括6763个汉字和682个其它符号 95年重新修订了编码,命名GBK1.0,共收录了21886个符号. 之后又推出了GBK18030编码,共收录了2

Python2.x中str与unicode相关问题的解决方法_python

python2.x中处理中文,是一件头疼的事情.网上写这方面的文章,测次不齐,而且都会有点错误,所以在这里打算自己总结一篇文章. 我也会在以后学习中,不断的修改此篇博客. 这里假设读者已有与编码相关的基础知识,本文不再再次介绍,包括什么是utf-8,什么是unicode,它们之间有什么关系.str与字节码 首先,我们完全不谈unicode.   s = "人生苦短" s是个字符串,它本身存储的就是字节码.那么这个字节码是什么格式的? 如果这段代码是在解释器上输入的,那么这个s的格式就是

编码相关

字典上定义  Unicode:万国码 (一种国际标准字符集, 为世界上绝大多数已知的字符集定义了唯一的16位数值)  区别  ASCII:8位,单字节,可表示256个字符,美国标准,可满足大多数拉丁语系国家的要求.  Unicode:16位,双字节,了表示65536个字符,基本满足各国语言的编码.  简单的说,Unicode扩展自ASCII,可以理解为Unicode是ASCII的补充.   展望  Unicode征服ASCII 成互联网最常用编码.  Google资深国际软件架构师Mark Da

深入剖析JSP和Servlet对中文的处理

js|servlet|中文 世界上的各地区都有本地的语言.地区差异直接导致了语言环境的差异.在开发一个国际化程序的过程中,处理语言问题就显得很重要了. 这是一个世界范围内都存在的问题,所以,Java提供了世界性的解决方法.本文描述的方法是用于处理中文的,但是,推而广之,对于处理世界上其它国家和地区的语言同样适用. 汉字是双字节的.所谓双字节是指一个双字要占用两个BYTE的位置(即16位),分别称为高位和低位.中国规定的汉字编码为GB2312,这是强制性的,目前几乎所有的能处理中文的应用程序都支持

深入剖析JSP和Servlet对中文的处理过程

js|servlet|过程|中文 概述 世界上的各地区都有本地的语言.地区差异直接导致了语言环境的差异.在开发一个国际化程序的过程中,处理语言问题就显得很重要了. 这是一个世界范围内都存在的问题,所以,Java提供了世界性的解决方法.本文描述的方法是用于处理中文的,但是,推而广之,对于处理世界上其它国家和地区的语言同样适用. 汉字是双字节的.所谓双字节是指一个双字要占用两个BYTE的位置(即16位),分别称为高位和低位.中国规定的汉字编码为GB2312,这是强制性的,目前几乎所有的能处理中文的应