UTF-8编码
介绍 UTF-8 编码
UTF-8 是一种针对 Unicode 的可变长度字符编码。
针对 Unicode:UTF-8 是 Unicode 的实现方式之一。相当于 Unicode 规定了字符对应的代码值,这个代码值需要转换为字节序列的形式,用于数据存储、传输。代码值到字节序列的转换工作由 UTF-8 来完成。
可变长度字符编码:UTF-8 使用一至四个字节对 Unicode 字符集中的所有有效代码点进行编码。
- UTF-8 使用 1 个字节表示 ASCII 字符;
- UTF-8 使用 2 个字节表示带有附加符号的拉丁文、希腊文等;
- UTF-8 使用 3 个字节表示其他基本多文种平面(BMP)中的字符(包含了大部分常用字,如大部分的汉字);
- UTF-8 使用 4 个字节表示 Unicode 辅助平面的字符。
技术是为了解决问题而生的,UTF-8 编码是为了解决什么问题而设计的呢?UTF-8 是为了兼容 ASCII 编码而设计的。
ASCII 编码使用 1 个字节表示 ASCII 字符,而 Unicode 最初规定使用 2 个字节来表示所有的 Unicode 字符。如果使用 2 个字节来表示 ASCII 字符的话,那么含有大量 ASCII 字符的文本将浪费大量的存储空间。
UTF-8 编码使用 1 个字节来表示 ASCII 字符,而且字面与 ASCII 码的字面一一对应,这使得原来处理 ASCII 字符的软件无须或只须做少部分修改,即可继续使用。
UTF-8 编码的规则
Unicode 和 UTF-8 之间的转换关系表(x 字符表示码点占据的位)
码点的位数 | 码点起值 | 码点终值 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | |
---|---|---|---|---|---|---|---|---|---|
7 | U+0000 | U+007F | 1 | 0xxxxxxx | |||||
11 | U+0080 | U+07FF | 2 | 110xxxxx | 10xxxxxx | ||||
16 | U+0800 | U+FFFF | 3 | 1110xxxx | 10xxxxxx | 10xxxxxx | |||
21 | U+10000 | U+1FFFFF | 4 | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | ||
26 | U+200000 | U+3FFFFFF | 5 | 111110xx | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | |
31 | U+4000000 | U+7FFFFFFF | 6 | 1111110x | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx |
UTF-8 编码的规则:
- 在 ASCII 码范围内的代码点,UTF-8 使用 1 个字节表示。
- 大于 ASCII 码范围的代码点,UTF-8 使用多个字节表示。UTF-8 使用第一个字节的前几位表示该 Unicode 字符的字节长度(第一个字节的开头 1 的数目就是该 Unicode 字符的字节长度),其余字节的前两位固定为 10,作为标记
- 如果第一个字节的前两位为 1,第三位为 0(110xxxxx),则表示 UTF-8 使用 2 个字节表示该 Unicode 字符;
- 如果第一个字节的前三位为 1,第四位为 0(1110xxxx),则表示 UTF-8 使用 3 个字节表示该 Unicode 字符;
- 依此类推;
- 如果第一个字节的前六位为 1,第七位为 0(1111110x),则表示 UTF-8 使用 6 个字节表示该 Unicode 字符;
UTF-8 编码的字节含义:对于 UTF-8 编码中的任意字节 B:
- 如果 B 的第一位为 0(0xxxxxxx),则 B 独立的表示一个 ASCII 字符;
- 如果 B 的第一位为 1,第二位为 0(10xxxxxx),则 B 为一个多字节表示的字符中的一个字节;
- 如果 B 的前二 / 三 / 四 / 五 / 六位为 1,其余位为 0,则 B 为二 / 三 / 四 / 五 / 六个字节表示的字符中的第一个字节。
UTF-8 编码示例
Unicode/UTF-8-character table (utf8-chartable.de)
通过 UTF-8 编码表,我们可以看到中文字符 “一” 的 Unicode 代码点为 “U+4E00”,UTF-8 编码结果为 “e4 b8 80”,
对中文字符 “一” 进行 UTF-8 编码,是如何得到 “e4 b8 80” 的呢?我们下面来看。
“4E00” 的二进制表示为 “0100 1110 0000 0000”。
UTF-8 使用 3 个字节表示常用的汉字,因此中文字符对应的字节序列格式为:“1110xxxx 10xxxxxx 10xxxxxx”
于是中文字符 “一” 的 UTF-8 编码结果为 “11100100 10111000 10000000”,它的十六进制表示为 “e4 b8 80”
public static void main(String[] args) throws UnsupportedEncodingException {byte[] bytes = "一".getBytes("UTF-8");// [-28, -72, -128]System.out.println(Arrays.toString(bytes));
}
UTF-8 编码的优劣局限
UTF-8 编码的优点
UTF-8 和 ASCII 兼容:ASCII 是 UTF-8 的一个子集。因为一个纯 ASCII 字符串也是一个合法的 UTF-8 字符串,所以现存的 ASCII 文本不需要转换。为传统的扩展 ASCII 字符集设计的软件通常可以不经修改或很少修改就能与 UTF-8 一起使用。
任何面向字节的字符串搜索算法都可以用于 UTF-8 的数据(只要输入仅由完整的 UTF-8 字符组成)。UTF-8 可以保证一个字符的字节序列不会包含在另一个字符的字节序列中。而有些比较旧的可变长度字符编码(如Shift JIS)没有这个特质,故它们的字符串搜索算法变得相当复杂。
**UTF-8 字符串可以由一个简单的算法可靠地识别出来。**由于 UTF-8 字节序列的设计,如果一个疑似为字符串的序列被验证为 UTF-8 编码,那么我们可以有把握地说它是 UTF-8 字符串。一个字符串在任何其它编码中表现为合法的 UTF-8 的可能性很低,可能性随着字符串长度的增长而减小。 举例说明,字符值 C0、C1、F5 至 FF 从来没有出现。为了更好的可靠性,可以使用正则表达式来统计非法过长和替代值(可以查看W3 FAQ: Multilingual Forms上的验证 UTF-8 字符串的正则表达式)。
UTF-8 编码可以通过屏蔽位 和 移位操作快速读写:屏蔽位是指将字节的高位置零,以便获取低位的值;移位操作是指将字节的低位移动到高位,以便获取高位的值。这样,可以快速读取和写入 UTF-8 编码的字符。
UTF-8 编码的缺点
UTF-8 编码不利于使用正则表达式进行读音检索
正则表达式可以进行很多高级的英文模糊检索。比如,[a-h] 表示 a 到 h 间的所有字母。
同样 GBK 编码的中文也可以这样利用正则表达式,比如在只知道一个字的读音而不知道怎么写的情况下,也可用正则表达式检索,因为 GBK 编码是按读音排序的。虽然正则表达式检索并未考虑中文的多音字,但是由于中文的多音字数量不多,不少多音字还是同音不同调类型的多音字,所以大多数情况下正则表达式检索是还可以接受的。
但是 Unicode 汉字不是按读音排序的,它是按部首排序,所以不利于用正则表达式进行读音检索。在只知道一个字的部首而不知道如何发音的情况下,UTF-8 可用正则表达式检索而 GBK 不行。
UTF-8 的 ASCII 字符只占用一个字节,比较节省空间,但是更多字符的 UTF-8 编码占用的空间就要多出1/2,特别是中文、日文和韩文(CJK)这样的方块文字,它们大多需要三个字节。
无法根据 Unicode 字符数判断出 UTF-8 文本占用的字节数。因为 UTF-8 是一种可变长度字符编码。
参考资料
UTF-8 - 维基百科,自由的百科全书 (wikipedia.org)
Unicode/UTF-8-character table (utf8-chartable.de)
相关文章:

UTF-8编码
介绍 UTF-8 编码 UTF-8 是一种针对 Unicode 的可变长度字符编码。 针对 Unicode:UTF-8 是 Unicode 的实现方式之一。相当于 Unicode 规定了字符对应的代码值,这个代码值需要转换为字节序列的形式,用于数据存储、传输。代码值到字节序列的转…...

likeshop单商户SaaS版V1.8.2说明!
likeshop单商户SaaS版V1.8.2主要更新如下: 新增 前端登录引导用户填写头像昵称 PC端—注册页面显示服务协议和隐私政策 PC端—首次进入商城弹出协议提示 PC端—结算页新增门店自提的配送方式 后台—PC端菜单导航栏的跳转链接支持添加自定义链接 优…...

算法训练营 day46 动态规划 最后一块石头的重量 II 目标和 一和零
算法训练营 day46 动态规划 最后一块石头的重量 II 目标和 一和零 最后一块石头的重量 II 1049. 最后一块石头的重量 II - 力扣(LeetCode) 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合…...

nginx-host绕过实例复现
绕过Nginx Host限制第一种处理方法Nginx在处理Host的时候,会将Host用冒号分割成hostname和port,port部分被丢弃。所以,我们可以设置Host的值为2023.mhz.pw:xxx"example.com,这样就能访问到目标Server块:第二种处理…...
Java学习记录day9
类与对象 内部类 成员内部类 在一个类的内部定义的类。 public class Outer {private int a 10;public void outMethod() {System.out.println("这是外部类中的方法");}// 成员内部类public class Inner{private int b 10;public void innerMethod() {// 外部类…...

ActiveReports.NET 17.0 Crack by Xacker
一个完整的报告解决方案,用于在您的业务应用程序中设计、定制、发布和查看报告。 ActiveReports.NET 通过直观的 Visual Studio 集成报表设计器和丰富的控件帮助您提供精美的报表。ActiveReports 提供基于代码的跨平台报告、易于使用的设计器和灵活的 API。适用于桌…...

【计算机网络】传输层TCP协议
文章目录认识TCP协议TCP协议的格式字段的含义序号与确认号六个标志位窗口大小确认应答(ACK)机制超时重传机制连接管理机制三次握手四次挥手滑动窗口流量控制拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况总结认识TCP协议 传输控制协议 (TCP,T…...

Mysql5.7安装【Windows版】
文章目录一、下载二、添加到环境变量三、添加配置文件my.ini四、安装Mysql 修改密码一、下载 下载地址 滑倒最下面有一个MySQL Community Server 选择要下载的版本 二、添加到环境变量 下载好了之后开始解压 把bin目录添加到环境变量 可以点击进入bin目录,直接复…...

分布式一致性算法Raft原理图释
什么是分布式一致性算法Raft 分布式一致性算法Raft:指在分布式场景下实现集群数据同步的解决方案 掌握了这个算法,就可以较容易地处理绝大部分场景的容错和数据一致性需求 Raft三大角色 跟随者(Follower):普通群众…...

网络安全-字典生成-crunch
网络安全-字典生成-crunch crunch工具,在kali已经集成好了 2是代表最小字符长度 4是最大字符长度 生成了一个2M的文件 还有我们来查看这个密码本 从abcd26个英文字母的2位到4位的组合,他全部排列了一次 还可以自定义数字,特殊字符…...
闪光桐人の实习日记
2023年2月13日 1,认识了职场礼仪,学习了职场礼仪的重要性 尊重->心情愉悦->建立信任与好感->合作机遇的敲门砖 2,学习了职场礼仪中的邮件礼仪 模板管理中设置自己的名片 部门写到三级部,如果部门名太长要换一行 发送…...
PostgreSQL 常见配置参数
max_wal_size : 两个检查点(checkpoint)之间,WAL可增长的最大大小,即:自动WAL checkpoint允许WAL增长的最大值。该值缺省是1GB。如果提高该参数值会提升性能,但也是会消耗更多空间、同时会延长崩溃恢复所需…...

JAVA 常用类型之String结构
String在java中我们是用来操作字符串的,但它的底层结构确是一个char[]数组,通过数组的方式将每个字符进行保存。 使用时:String str"ABCD",内部存value确是:value[A,B,C,D]; 如下图: 参考String源…...

二三层网络设备封装与解封装原理
1、寻址转发(寻址指的是寻找IP地址) 路由表放在一个公共的地方,比如主控板上,由主控板 的CPU运行路由协议,计算路由,生成和维护路由表。 转发表与路由表: 转发表是根据路由表生成的。路由表中…...

9、MyBatis框架——使用注解开发实现数据库增删改查操作、一级缓存、二级缓存、MyBatis实现分页
目录 一、使用注解开发实现数据库增删改查操作 1、搭建项目 2、使用注解开发操作数据库 二、一级缓存 1、一级缓存失效的情况 三、二级缓存 1、手动开启二级缓存cacheEnabled 2、二级缓存机制 四、MyBatis实现分页 1、配置环境 2、startPage()开启分页 3、PageInfo…...

C++STL剖析(六)—— set和multiset的概念和使用
文章目录🌟 前言🍑 树型结构和哈希结构🍑 键值对1. set的介绍和使用🍑 set的模板参数列表🍑 set的构造🍑 set的使用🍅 insert🍅 find🍅 erase🍅 swap…...

SpringColud第四讲 Nacos的Windows安装方式和Linux的安装方式
在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码: 目录 1.Windows安装Nacos 1.1.下载 1.2.解压 1.3.修改相关配置: 1.4.启动: 1.5.登录: 2.Linux的安装方式Nacos 2.1.…...

微服务项目【网关服务限流熔断降级分布式事务】
网关服务限流熔断降级 第1步:启动sentinel-dashboard控制台和Nacos注册中心服务 第2步:在网关服务中引入sentinel依赖 <!-- sentinel --> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-…...

【情人节用Compose给女神写个爱心动画APP】
情人节用Compose给女神写个爱心动画APP前言涉及知识点实现思路实现过程绘制爱心创建动画效果Preview预览效果完整源码彩蛋前言 前一阵子看电视里的学霸用代码写了个炫酷的爱心,网上有很多js和python的源码,复制粘贴就能拥有,但是Android的好…...

GUI swing和awt
GUI(Graphical User Interface,简称 GUI,图形用户界面)是指采用图形方式显示的计算机操作用户界面,与早期计算机使用的命令行界面相比,图形界面对于用户来说在视觉上更易于接受。Java GUI主要有两个核心库&…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

PydanticAI快速入门示例
参考链接:https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...