首页 > 其他分享 >Unicode文字编码

Unicode文字编码

时间:2023-07-15 16:46:16浏览次数:35  
标签:文字 编码 UTF 字节 16 Unicode 字符

前言:

Unicode 有多种存储方式,常见的有 UTF-8、UTF-16、UTF-32,它们分别用不同的二进制格式来表示 Unicode 字符

UTF-8、UTF-16、UTF-32 中的 "UTF" 是 "Unicode Transformation Format" 的缩写,意思是"Unicode 转换格式",后面的数 字表明至少使用多少个比特位来存储字符, 比如:UTF-8 最少需要8个比特位也就是一个字节来存储,对应的, UTF-16 和 UTF-32 分别需要最少 2 个字节 和 4 个字节来存储

Unicode

​ 世界上存在多种各样的编码方式,不同国家地区都有过自己地区的编码格式,这会导致同一个二进制数字,在不同的地区,被解释成不同的符号。

​ 这时候Unicode代码就为此而生,他将世界上所有的符号都收纳其中,并且给每一个符号一个对应的唯一二进制代码(编码)。目前Unicode码表的规模已经达到了100多万个符号。

​ 同时Unicode的前128个字符编码和ASSCII是一样的,这就说明Unicode兼容ASCII,即使用ASCII编码的程序可以直接用Unicode

Unicode的衍生问题

​ Unicode表能想象成为一本书,书中记录着每个字符对应的二进制代码编号,但是他没规定这个二进制的编号该如何存储。

​ 简单理解的意思就是:计算机在读取字节的时候,他需要一套规范化方式,来做到--->读取多少个字节为一个字符---->开始转译--->转译成目标字符。

​ 这时候就产生了UTF-32、UTF-16、UTF-8这三种编码存储方式

UTF编码

​ Unicode字符编码格式(Unicode Transformation Formats),简写为:UTF,即:将一个Unicode字符保存为字节序列的格式规范,用于文件存储、数据传输等。

UTF-8编码

首先要了解到UTF-8的编码格式,他是一种可变长度的编码,他的编码规则如下:

UTF-8编码方式(二进制)
一字节 0xxxxxxx
两字节 110xxxxx 10xxxxxx
三字节 1110xxxx 10xxxxxx 10xxxxxx
四字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

案例:

“莞”的Unicode对应编码是839E(十六进制)

换算成二进制:1000 0011 1001 1110

绝大多情况下汉字在UTF-8中是三字节,而“莞”对应的二进制占16位,和三字节的能填入位数吻合(15位那些补0即可)

测试结果:

UTF-16编码

​ 对于UTF-16编码是一种怎么样的编码,我查了很多资料,但是发现大家说的各异:有说他是一种定长两字节的编码方式、也有说他是一种可变不定长的编码方式(因为可以由两个字节或者四个字节来表示字符) 对此整理到以下笔记:

> UTF-16(Unicode Transformation Format-16)是一种定长的字符编码方式。在UTF-16中,每个字符通常由16位(2个字节)表示,但有一些特殊字符需要由32位(4个字节)表示。

> UTF-16使用了一种称为"码元(code unit)"的单位来表示字符。每个码元都由16位表示,并且可以表示一个基本多文种平面(Basic Multilingual Plane,BMP)中的字符。如果遇到位于辅助平面(Supplementary Planes)的字符,需要使用两个码元来表示。

> 因为UTF-16采用定长编码,所以每个字符在内存中占用的空间是固定的。需要注意的是,虽然UTF-16是定长编码,但它并不意味着每个字符都占用相同的存储空间。由于一些字符需要使用两个码元表示,因此一些字符可能会占用4个字节的空间。

> Unicode字符集被划分为两个主要部分:
> 基本多文种平面(Basic Multilingual Plane,BMP)和辅助平面(Supplementary Planes)。

> 基本多文种平面(BMP)涵盖了Unicode代码点范围从U+0000到U+FFFF的字符。这包括了大部分常用的字符,如拉丁字母、汉字、数字、标点符号等。基本多文种平面的字符可以使用一个码元(16位,2个字节)来表示。

> 辅助平面(Supplementary Planes)是位于基本多文种平面之外的字符范围。它包括了Unicode代码点范围从U+10000到U+10FFFF的字符。辅助平面中的字符无法通过单个码元来表示,需要使用两个码元(32位,4个字节)的代理对(surrogate pair)来表示。

> 辅助平面的划分边界是在U+FFFF和U+10000之间。U+FFFF是基本多文种平面的最后一个代码点,而U+10000是辅助平面的第一个代码点。

> 通过将辅助平面划分出来,Unicode可以容纳更广泛的字符集,包括一些特殊的符号、表情符号、历史文字等。

在这一大串文字可能很难理解,用我自己理解的话语就是:

在UTF-16中,由于两字节装不下Unicode收录的所有字符

所以用两字节的最小值到两字节的最大值0000~FFFF(十六进制)来划分为基本多文种平面

十六进制:0000->二进制:0000 0000 0000 0000

十六进制:FFFF->二进制: 1111 1111 1111 1111

而以FFFF高一位的10000为边界规定:10000~10FFFFF辅助平面

十六进制:10000->二进制:0001 0000 0000 0000 0000

十六进制:10FFFF->二进制:0001 0000 1111 1111 1111 1111   //注意到辅助平面的最大边界并不是填满4字节

​ 此时UTF-16的编译过程就变成了先判断字符Unicode表与10000(十六进制)的关系,也就是和码点65536(十进制)的关系。对于小于65536的字符,他的编译过程是直接转换成2个字节长的二进制数即可,而对于大于65536的码点他的编译过程比较麻烦。以下是UTF-16的一个编译流程:

如果码点<65536

如果码点>65536

** 码点>65536时候的流程图**

部分误区知识点:

UTF-16编码的资料补充

UTF-16并非是由于16个字节不够用才引入基本多文种平面(BMP)和辅助平面的划分的。实际上,UTF-16的设计初衷是为了向后兼容早期的Unicode实现。

早期的Unicode版本采用的是16位编码方案,其中每个字符都用16位(2个字节)表示。这被称为UCS-2(Universal Character Set-2),它可以表示65,536个字符,也就是Unicode代码点范围从U+0000到U+FFFF的字符。

然而,随着Unicode字符集的不断扩展,发现16位的编码空间不足以容纳所有字符。为了能够表示更多的字符,Unicode引入了辅助平面(Supplementary Planes),其中包含了位于U+10000到U+10FFFF范围的字符。

为了向后兼容UCS-2编码,UTF-16编码方案被设计出来。UTF-16使用16位码元来表示基本多文种平面(BMP)中的字符,而对于位于辅助平面的字符,使用代理对(surrogate pair)的方式,即两个16位码元(共四个字节)表示一个字符。

因此,UTF-16的设计是为了兼容早期的Unicode实现,并且能够适应Unicode字符集的扩展。它提供了一种灵活的编码方案,可以同时表示基本多文种平面和辅助平面的字符。

UTF-32编码

UTF-32是一种定长的编码方式,他的存储方式是:每4个字节表示一个字符。(被淘汰)

UTF-32缺点:

(1)存储简单字符时候浪费空间

案例:

存储字母a

其Unicode表中为:01100001

但是在UTF-32中为:00000000   00000000   00000000   01100001

(2)导致通信效率变低

UTF-32优点:

不用脑子,很暴力

UTF-8和UTF-16优缺点的比较

​ UTF16的存储格式是任意字符对应的数字都是两个字节或者四个字节来保存。

​ 对于英文来讲,明明可以用一个字节能表示出来的,偏偏要用两个字节来表示,这造成了不必要的空间浪费。

​ 但是对于非英文文字的来说,使用UTF-8会有性能浪费(因为要根据UTF-8编码规则解码,要在每个字节前做判断)

于是UTF-8和UTF-16的优劣很容易就看出来了.

如果全部英文或英文与其他文字混合,但英文占绝大部分,用UTF-8就比UTF-16节省了很多空间.

而如果全部是中文这样类似的字符或者混合字符中中文占绝大多数.UTF-16就占优势了,可以节省很多空间.[3]

UTF-16优缺点整理:

缺点:

1.UTF-16能表示的字符只有6万多

​ 这是网络上大家认为的缺点,但是GPT中我了解到UTF-16能容纳的数量,远超6万个字符

GPT回答:
UTF-16能够表示的字符数量取决于Unicode字符集中的范围。Unicode定义了一共1,114,112个可能的代码点。

在UTF-16中,基本多文种平面(BMP)的字符使用单个码元(16位,2个字节)表示,可以表示65,536个代码点(U+0000到U+FFFF)。

辅助平面的字符需要使用代理对(surrogate pair)表示,每个代理对由两个码元(32位,4个字节)组成。辅助平面有1,048,576个代码点(U+10000到U+10FFFF),因此UTF-16可以表示这个范围内的字符。

所以,UTF-16总共能够表示基本多文种平面(BMP)和辅助平面中的1,114,112个Unicode代码点。需要注意的是,并非所有的Unicode代码点都有对应的字符或者被分配了字符。实际上,Unicode字符集中只有一部分被分配给了具体的字符,而剩余的空间被保留用于未来的扩展。

​ 个人理解是UTF-16中,用两个字节是最优的存储方式,但只能收纳到6万多个字,再往后必须要使用辅助平面字符,但是辅助平面字符的编译过程需要的性能是个大缺点。

2.UTF-16 存在大小端字节序问题

这个问题在进行信息交换时特别突出——如果字节序未协商好,将导致乱码;如果协商好,但是双方一个采用大端一个采用小端,则必然有一方要进行大小端转换,性能损失不可避免(大小端问题其实不像看起来那么简单,有时会涉及硬件、操作系统、上层软件多个层次,可能会进行多次转换)> > > >

​ 这个同样是网上所描述到的缺点,但是我没能理解原因。

3.容错率低

​ 当其中每个字节或者每个比特位丢失时候,会导致这个数据全部错乱,没办法纠错

4.部分文字空间利用率低

​ 对于英文来讲,明明可以用一个字节能表示出来的,偏偏要用两个字节来表示,这造成了不必要的空间浪费。

优点:

1.部分文字性能效率与空间存储率高:

​ 如果某种文字他的Unicode表处于0000 0001 0000 0000 到 1111 1111 1111 1111之间那么他就很合适UTF-16

UTF-8的优缺点整理:

缺点:

1.使用地区不平衡

文字出现频率在Unicode中,常在三个字节以上的国家而言空间冗余程度增加了。

而对于英语为母语的国家来说是非常方便的,因为他兼容了ASCII编码,存储空间上完全不浪费

2.变长编码的性能问题

优点:

1.字符空间足够大

2.不存在大小端字节序问题,信息交换时非常便捷

3.容错性高,局部的字节错误(丢失、增加、改变)不会导致连锁性的错误,因为 UTF-8 的字符边界很容易检测出来

资料来源:

[1]: Unicode 和 UTF-8 之间的关系转载\ - Tsingke - 博客园 (cnblogs.com)(https://www.cnblogs.com/tsingke/p/10853936.html)
[2]: 一听就懂字符集、ASCII、GBK、UTF-8、Unicode、乱码、字符编码、解码问题的讲解_哔哩哔哩_bilibili(https://www.bilibili.com/video/BV1xD4y1y7yc/?spm_id_from=333.337.search-card.all.click&vd_source
[3]: Unicode、UTF-8、UTF-16之间的区别 - 知乎 (zhihu.com)(https://zhuanlan.zhihu.com/p/259386795)

标签:文字,编码,UTF,字节,16,Unicode,字符
From: https://www.cnblogs.com/ethereal258/p/17556236.html

相关文章

  • 计算机中的数制与编码(二进制转换)
    一、进制表示1.十进制表示使用(0,1,2,...,9)十位数字表示,十进制运算时逢十进一。2.二进制表示使用(0,1)两个数字表示,二进制运算时逢二进一。3.十六进制表示使用数字和符号(0-9,A-F)表示,十六进制运算时逢十六进一。对于任意进制数的表示N,我们把数字k在N中的位置称为序号,用i表示(序......
  • mysql修改所有表的编码排序规则
    #查询数据库各表的排序规则SELECTTABLE_NAME,TABLE_COLLATIONFROMINFORMATION_SCHEMA.TABLESWHERETABLE_SCHEMA='database'; #查询要修改排序规则表的SQL语句SELECTconcat('ALTERTABLE',TABLE_NAME,'CONVERTTOCHARACTERSETutf8mb4COLLATEutf8mb4_unicod......
  • dede会员中心投稿编辑器修改成纯文字投稿方式
    在我们后台发布文章的时候往往需要加入HTML或css以及php等语言的代码,若是单独发的话,没有颜色的区分,并且人看观看的效果也不是很好,所以需要实现后台能编辑语言代码的,之前我们处理了织梦后台的编辑器,现在我来说一下会员后台的编辑器怎么实现这个功能。一:首先打开根目录下的:/member/......
  • 算法——格雷编码、霍夫曼编码
    格雷编码当n=0时,格雷码序列为[0]。将n-1编码翻转,翻转部分的n-1位设置位1,获得n位编码。霍夫曼编码那么为什么通过哈夫曼编码后得到的二进制码不会有前缀的问题呢?这是因为在哈夫曼树中,每个字母对应的节点都是叶子节点,而他们对应的二进制码是由根节点到各自节点的路径所决定......
  • 多通道cPCI接口值编码器信号采集
    可同时实现与4路 ENDAT2.2值码盘数据通讯,读取25位或29位等精度的码盘位置信息。l  支持ENDAT2.2标准l  通讯距离达30米以上l  支持PCI和CPCI接口l  双V68接口l  支持常用25位或29位码盘及其它标准ENDAT2.2码盘l  支持由板卡向码盘供电l  支持定制化修改FPGA......
  • 2023-07-13:如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串
    2023-07-13:如果你熟悉Shell编程,那么一定了解过花括号展开,它可以用来生成任意字符串。花括号展开的表达式可以看作一个由花括号、逗号和小写英文字母组成的字符串定义下面几条语法规则:如果只给出单一的元素x,那么表达式表示的字符串就只有"x"。R(x)={x}例如,表达式"a"......
  • 学习霍夫曼编码
    霍夫曼编码广泛用于数据压缩算法,其重要性不言而喻。内容:写一个程序读ASCII文件,统计各字符的频率并制定霍夫曼编码表,最后将此文件的内容根据编码表翻译为二进制文件,计算压缩率。代码清单:#include...typedefstruct{floatweight;intparent,lc,rc;}node;#define......
  • redis数据结构编码优化(1)
    redis数据结构内部编码优化(1)Redis可以通过内部编码规则来节省空间。Redis为每种数据类型提供了两种内部编码方式。以散列类型为例,散列类型是通过散列表实现的,这样就可以实现o(1)时间复杂度的查找、赋值操作,然而当键中元素很少的时候,o(1)的操作并不会比o(n)有明显的性能提高,所以这......
  • Media Encoder 2023-视频编码软件mac/win版
    AdobeMediaEncoder2023是Adobe公司推出的一款专业的媒体编码和转换软件。作为AdobeCreativeCloud套件的一部分,它与其他Adobe创意应用程序(如PremierePro、AfterEffects)无缝集成,提供了一个强大的工具集,用于优化、转换和编码各种媒体文件。→→↓↓载MediaEncoder2......
  • 封装图片处理工具类,实现图片的裁剪、压缩、图片水印、文字水印、多行文字水印等功能
    目录一、前言二、工具类的依赖和简单介绍1、添加依赖2、简单的使用3、加载需要处理的图片4、添加图片处理规则4.1Builder的方式4.2使用规则工厂的方式5、输出处理后的图片三、使用方式1、图片裁剪图片裁剪规则实体类1.1按长宽裁剪1.1.1示例代码1.1.2实现效果1.2按比例裁剪1......