惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
A
About on SuperTechFans
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Blog — PlanetScale
Blog — PlanetScale
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
Vercel News
Vercel News
G
Google Developers Blog
J
Java Code Geeks
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
Cloudbric
Cloudbric
L
LINUX DO - 最新话题
MyScale Blog
MyScale Blog
H
Heimdal Security Blog
PCI Perspectives
PCI Perspectives
Attack and Defense Labs
Attack and Defense Labs
S
Security @ Cisco Blogs
Latest news
Latest news
I
Intezer
L
Lohrmann on Cybersecurity
C
CXSECURITY Database RSS Feed - CXSecurity.com
月光博客
月光博客
T
Threatpost
博客园 - 【当耐特】
S
Schneier on Security
P
Privacy International News Feed
G
GRAHAM CLULEY
T
Tenable Blog
AWS News Blog
AWS News Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
雷峰网
雷峰网
博客园 - Franky
Engineering at Meta
Engineering at Meta
美团技术团队
S
Secure Thoughts
T
Troy Hunt's Blog
Microsoft Security Blog
Microsoft Security Blog
SecWiki News
SecWiki News
V
Visual Studio Blog
人人都是产品经理
人人都是产品经理
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Cisco Talos Blog
Cisco Talos Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Martin Fowler
Martin Fowler
Webroot Blog
Webroot Blog
Google DeepMind News
Google DeepMind News
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - Liaofy

前端新范式:用 AI 提效开发,用 E2E 保证迭代质量 把SPA的加载速度提升一倍,有没有搞头? 使用mumu模拟器抓包 andriod app 如何在本地给 vue-router4 扩展功能? Vue3 路由优化,使页面初次渲染效率翻倍 【eslint 插件开发】禁用 location 跳转外部链接 vue 项目使用 charles 代理线上页面到本地后显示404 避免使用单个数字作为对象的key 高扩展弹出层组件设计实现(H5&小程序) 轻松搞懂POST与PUT的区别 vite(or rollup) 实现 webpackChunkName webapp项目架构畅想(vue3).md vite试玩:老项目启动从6分钟到秒开 修剪AST树减少webapck打包尺寸 【uniapp】改善中大型uniapp小程序项目开发体验 vscode 调试 webpack 打包 deAsync.js 真正让异步变同步 盘的转——使用缓动函数完成动画 多个请求间断失败,如何优雅处理?
5分钟,搞清 Unicode 与 UTF-8 的区别
Liaofy · 2021-10-13 · via 博客园 - Liaofy

Unicode 是什么?

Unicode,官方中文名称“统一码”。通常大家谈到的 Unicode 一般指字符集的意思,但 Unicode 标准实际涵盖两个方面的内容:

  • Unicode 字符集
  • Unicode 编码

Unicode 字符集

Unicode 为每个字符提供一个唯一数字(码点 code point),记为“U+xxxx”,其中xxxx是码位转换成16进制后的结果。

字符->码位的集合即 Unicode 字符集,也称作通用字符集(英语:Universal Character Set, UCS)。可在这里查询字符对应的码位。

例如「中」的码点是 20013,记作 U+4E2D(20013 的十六进制为 0x4E2D)。它的二进制为100111000101101,这至少需要2个字节才能存储到计算机中。那为什么我们看到的是一个个字符,而不是二进制数呢?

Unicode 编码

Unicode 字符集规定了字符对应的唯一码点,但在实际的传输、存储过程中,为了兼顾各系统平台的差异、节省空间,需要对字符集进行编码——将对应的码点转换成另一种格式,即Unicode转换格式(Unicode Transformation Format,简称 UTF)。

Unicode 编码规则决定了码点如何在文件中显示,我们熟知的UTF-8 UTF-16就是编码规则的不同版本。

UTF-8 编码过程

UTF-8 是一种针对 Unicode 的可变长度字符编码,根据码点的大小,将其编码为 1 到 4 个字节,具体规则如下:

U+0000  - U+007F:   0xxxxxxx (1个字节)
U+0080  - U+07FF:   110xxxxx 10xxxxxx (2个字节)
U+0800  - U+FFFF:   1110xxxx 10xxxxxx 10xxxxxx (3个字节)
U+10000 - U+10FFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (4个字节)

「中」的码点为U+4E2D,由上表可知,它属于第三行,被编码成三个字节:

  4   E    2    D
0100 1110 0010 1101
-----------------------------
1110xxxx 10xxxxxx 10xxxxxx  // 上表第三行
____0100 __111000 __101101  // 将 4E2D 的二进制带入上面的格式中
-----------------------------
11100100 10111000 10101101  

以上就是字符「中」经过 UTF-8 编码后得到字节序列的过程,反之亦然。

Unicode 和 UTF-8 的区别

简单来说,Unicode 是【字符集】,UTF-8 是字符集的一种【编码规则】。但广义来讲,它们是包含关系,如下图:

+-----------------------------+
|           Unicode           |
|  +-----------------------+  |
|  |     通用字符集(UCS)     |  |
|  +-----------------------+  |
|  +------------------------+ |
|  |   UCS转换格式(UTF)      |  |
|  | +-------------------+  | |
|  | | UTF-8, UTF-16 ... |  | |
|  | +-------------------+  | |
|  +------------------------+ |
|                             |
+-----------------------------+

补充

字节、字符、字符串

  • 字节:计算机中存储数据的最小单元,一个8bit的二进制数,譬如0x01、0x45...
  • 字符:人类使用的一个个文字符号,在计算机中通常用英文单引号包裹,譬如'中'、'A'、'%'、'。'...
  • 字符串:多个字符 串联起来形成字符串,在计算机中通常用英文双引号包裹,譬如"中华人民共和国万岁"、"MAGA"...

字符以二进制数据形式存储在计算机中,我们在文件中看到的一个个字符,是根据某种编码规则转换后的结果。

字符串长度

同一个字符,在不同的编码规则下,它的长度也不一样。JavaScript 使用 UTF-16 编码,该编码使用 16 比特为1个编码单元来表示大部分常见的字符,使用两个代码单元表示不常用的字符。

'中'.length === 1 // true
'😀'.length === 2 // true

更进一步,我们用 rust 来检验这个规则:

fn main() {
  let s1 = "中";
  assert_eq!(s1.len_utf8(), 3);
  assert_eq!(s1.len_utf16(), 1);
}

最后回答自己一个问题,1个汉字几个字节?

引用

unicode 官网
维基百科-Unicode
维基百科-UCS
字符码点查询