浅谈Unicode与UTF-8

news2024/9/17 7:35:01

我们都知道,在Golang中字符都是以UTF-8编码的形式存储,当我们使用range遍历字符串的时候,go会为我们取出一个字符(rune)而不是一个byte,例如以下例子,我们使用range迭代取出第一个字符“你”,并且打印输出取出的字符编码以及内容,接着我们使用取址方法观察内存中实际存储的内容是什么。
在这里插入图片描述

先说结论:

迭代器取出的是字符的Unicode编码,而内存里实际存储的是UTF-8实现。
输出结果如下图所示:
在这里插入图片描述
我们可以发现,迭代器取出的内容与实际存储内容不一致,这是因为:迭代器取出的是字符的unicode编码,“你”在Unicode编码里是第20320位,而真正在计算机内的实现方法采用UTF-8编码方式,本文将详细解释如何实现unicode到UTF-8的转变。

Unicode

统一码(Unicode),也叫万国码、单一码,由统一码联盟开发,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。
统一码是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
统一码是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。统一码用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。

为什么需要UTF-8?

我们已经有了Unicode编码,就有了一本字典,给每个字符一个编码,字符集序号一直从0-0x10FFFF。但是问题在于,单纯使用Unicode编码无法让计算机判断出哪里是一个字符,例如
00000001 00000001,计算机应该看成257还是两个1呢?这就涉及到如何实现变长编码,让unicode能够最大化利用计算机内存。现在普遍的实现方法就是UTF-8编码方式,将Unicode通过一定的转换方法变为UTF-8,使得计算机能够识别不定长的字符编码。

UTF-8编码规则

  1. 对于单字节的符号(英文字符),字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。如 A 在ASCII中是65,对应二进制 0100 0001
  2. 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

ASCII有128个字符,所以就是一个字节的后七位,第一位0代表单字节。

如果第一位是1,那么代表字节不完全,为多字节字符。计算机读取第一个字节的1个数,读到0时统计读到了多少个1,据此判断此字符几个字节。

那么为什么我们不直接用1开头表示多字节字符呢?为什么后续的字节开头需要使用10?

假设我们将后续字节设计为以1开头,那么UTF-8编码中的多字节字符的字节格式可能会产生冲突。例如,假设一个多字节字符的编码为:

110xxxxx 10xxxxxx

现在,如果后续字节以1开头,我们无法判断这个1是作为后续字节的一部分,还是作为下一个字符的起始字节。这会导致解析错误,无法正确识别字符的边界。

有人问,那我第一个字节都已经知道后面以后几个字节了,为什么还要用10开头呢,直接8bit全部用上不是更好吗?

UTF-8使用变长编码,这意味着字符占用的字节数是可变的。通过在第一个字节中指示字符占用的字节数,我们可以确定如何解析后续字节。然而,如果后续字节使用完整的8位来表示字符信息,会导致解码时的歧义和错误。

如果后续字节使用全部8位,就无法准确判断一个字节是属于哪个字符。通过将后续字节以"10"开头,我们可以明确地指示它们是后续字节,并且解码器可以根据这个特定的模式来解析UTF-8序列。这种设计保证了解码的自同步性,即即使在传输过程中发生了错误或数据丢失,解码器仍然能够正确地恢复每个字符的边界。

简单概括就是,即使丢掉了第一个字节的信息,后续也能根据每个字节的开头来判断处于哪个位置!

因此,为了明确表示多字节字符的后续字节,UTF-8编码规定后续字节必须以10开头。这样,我们在解析时可以准确地识别出多字节字符的起始和后续字节,避免了歧义和解析错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/715496.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TechSmith Camtasia for Mac 2023.0.3 中文破解版 Win/Mac上强大的屏幕录像工具

Camtasia 是Win/Mac上最强大的屏幕录像工具之一,该软件集成了视频录制、编辑、导出等一系列功能,支持鼠标光标样式、草绘示意插图、冰冻区域等实用的功能,还具有移动客户端让你录制视频,然后通过无线传输到 Camtasia 中进行编辑&a…

判断数组中所有元素是否均为实数对象 numpy.isrealobj()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断数组中所有元素 是否均为实数对象 numpy.isrealobj() [太阳]选择题 请问关于以下代码的说法错误的是? import numpy as np a np.array([1, 2, 3]) b np.array([1, 1 2j, …

剑指 Offer 19: 正则表达式匹配

可能存在一个现象,就是aaab,然后a*ab,那么这样*只能代表一个a。 这道题可以使用动态规划的方式来解决。 这道题就是状态的判断:是否两个都为0?只有两个都为0才为true,并且判断*,有两个情况&…

Docker WebRTC容器部署方案

文章目录 WebRTC简介WebRTC Docker容器部署优势方案(mpromonet/webrtc-streamer)步骤 WebRTC简介 WebRTC(Web Real-Time Communication)是一种开放的实时通信技术,它允许浏览器之间进行音频、视频和数据的实时传输。W…

从古代八卦探究计算机的八进制

八进制,即八卦,是中国古代哲学体系中非常重要的一个概念,它被广泛应用于易经、道家、儒家等诸多领域。随着计算机科学的快速发展,人们开始思考:八进制是否可以应用到计算机上? 一、什么是八进制&#xff1…

Javaee技术目的总结

一.前节回顾 在前一节中,我们了解了: 1.将中央控制器中的Action容器,变成可控制! 2.针对于反射调用业务代码,最终页面跳转 3.jsp页面参数传递后台的代码优化字段太多有影响! 二.项目部署前期准备工作 1.项目运行环境…

c语言 va_start/va_end函数

c语言 va_satrt和va_end函数介绍 头文件&#xff1a;#include <stdarg.h> 函数原型&#xff1a;void va_start(va_list ap, last) 和 void va_end(va_list ap); 可以被参数数量和类型可变的函数调用。 可变参数用…&#xff08;3个省略号表示可变参数列表&#xff09; …

深入理解 http 反向代理

要理解什么是 反向代理(reverse proxy) , 自然你得先知道什么是 正向代理(forward proxy). 另外需要说的是, 一般提到反向代理, 通常是指 http 反向代理, 但反向代理的范围可以更大, 比如 tcp 反向代理, 在这里, 不打算讨论 tcp 之类的反向代理, 当文中说到反向代理时, 指的就是…

C++day5

2、 #include <iostream> using namespace std; static int blood 10000; class hero { protected:string name;int hp;int attack; public:hero(){}//无参构造hero(string name,int hp,int attack):name(name),hp(hp),attack(attack){}//有参构造virtual void Atk(){b…

使用supervisor管理进程

写目录 一、supervisor简介二 、supervisor安装2.1下载supervisor2.2配置文件详解2.3把squid服务加入到supervisor管理当中 一、supervisor简介 supervisor是Python开发的c/s服务&#xff0c;是Linux系统下的进程管理工具。可以监听、启动、停止、重启一个或多个进程用supervi…

卡尔曼滤波原理和使用

随着传感技术&#xff0c;机器人&#xff0c;自动驾驶等不断发展&#xff0c;对控制系统的精度以及稳定性要求越来越高。卡尔曼滤波作为一种状态最优估计方法&#xff0c;应用也越来越普遍、 对于Kalman Filter的理解&#xff0c;用过都知道“黄金五条”公式&#xff0c;且通过…

pytorch实战13:基于pytorch实现YOLOv1(长长文)

基于pytorch实现YOLOv1&#xff08;长长文&#xff09; 前言 ​ 本篇文章的目的是记录自己实现yolo v1的过程&#xff0c;在此过程中&#xff0c;参考了许多开源的代码和博客&#xff0c;赞美大佬们。 参考文献和代码 YOLO v1代码参考&#xff1a;&#xff08;读书人的事情&…

华为OD机试真题 Python 实现【猜字谜】【2023Q1 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述补充说明:四、解题思路五、Python算法源码六、效果展示1、输入2、输出3、说明一、题目描述 小王设计了一人简单的清字谈游戏,游戏的迷面是一人错误的单词,比如nesw,玩家需要猜出谈底库中正确的单词。猜中的要求如 对于某个谜面和…

武汉抖音seo,抖音关键词排名

抖音seo怎么做 抖音作为一款热门的社交娱乐应用&#xff0c;其SEO关键词排名对于提升内容曝光和用户流量非常重要。 1. 关键词研究&#xff1a;在进行SEO关键词排名时&#xff0c;首先需要进行关键词研究&#xff0c;了解用户在抖音上搜索的热门关键词。可以通过使用相关的关…

如何使用ArcGIS自定义图框样式

GIS制图过后&#xff0c;一般都会涉及到出图&#xff0c;大家肯定都希望自己的出图成果越美观越好&#xff0c;除了图本身之外&#xff0c;还可以从周边的一些修饰入手&#xff0c;比如图框&#xff0c;那么今天就给大家讲解一下如何自定义ArcGIS图框风格&#xff0c;希望能对大…

Docker-Dockerfile-DockerCompose的那些事

文章目录 一、Docker背景1.1 环境不一致1.2 隔离性1.3 弹性伸缩1.4 学习成本 二、Docker介绍2.1 Docker的由来2.2 Docker的思想 三、Docker的安装3.1 下载Docker依赖的环境3.2 指定Docker镜像源3.3 安装Docker3.4 Docker服务启停3.5 Docker容器运行解析3.6 Docker运行流程解析3…

暑期学JavaScript【第五天】

BOM Browser Object Model&#xff0c; 浏览器对象模型 DOM是BOM的一部分 1.navigator 用于判断当前的用户端。 用navigator.userAgent获取 2. location location.href www.baidu.com&#xff0c; 赋值后&#xff0c;执行直接跳转到百度location.search; 获取地址中?后面部…

maven查看jar的pom引入来源

从idea中点击 Maven Projects&#xff0c;后点击Show Dependencies&#xff0c;如图所示 得到依赖关系图&#xff0c;如下 在页面进行 Ctrl F 搜索需要的 Jar 名称 例&#xff1a;查找 spring-beans 双击框定的地方&#xff0c;就能进入到对应的pom文件 查找依赖关系 1、…

第三方库介绍——tslib库

文章目录 tslib 简介tslib 框架分析tslib 的框架 交叉编译、测试 tslibtslib应用程序 tslib 简介 tslib 是一个触摸屏的开源库&#xff0c;可以使用它来访问触摸屏设备&#xff0c;可以给输入设备添加各种“ filter ”( 过滤器&#xff0c;就是各种处理) 编译 tslib 后&#…

C语言学习准备-编辑器选择

今天继续给大家更新C语言经典案例 今天的案例会比昨天稍微有一些难度&#xff0c;但是同时还是非常经典的案例 本来是想给大家继续更新C语言经典案例&#xff0c;但是有朋友反应C语言编辑器的选择&#xff0c;刚好我自己也是想更换一下C语言的编辑器&#xff0c;跟大家分享一下…