utf8字符集对照表(GBK,UTF8是什么)

本文目录
- GBK,UTF8是什么
- Unicode字符集的UTF-32、UTF-16和UTF-8编码
- 为什么MYSQL要设定用UTF8MB4编码UTF8MB4
- Unicode(utf-8) 是什么意思
- utf8 中 有占4字节的中文字符吗
- utf-8的数字,英文,中文各自占用几个byte字节
GBK,UTF8是什么
GBK,UTF8都是一种字符集,就是一种编码方式~\x0d\x0a\x0d\x0a字符集(Characterset)是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,\x0d\x0a\x0d\x0a常见字符集名称:ASCII字符集、GB2312字符集、UTF8字符集、GB18030字符集、Unicode字符集等。\x0d\x0a\x0d\x0a计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。
Unicode字符集的UTF-32、UTF-16和UTF-8编码
什么是Unicode字符集?简单地说,它就是把全世界人类发明和使用的现有的所有字符进行了集中收集和逐一编码,这个过程就像把上学时老师把班里学生都叫到一起,统计总数后给每个学生分配一个唯一的学号一样。Unicode字符集里收录的字符可以是文字(如:‘α’、‘魍’等),也可以是符号(如:‘@’、‘$’),还可以是图形(如’:smiling_face:’等)。
那它有什么用呢?它有两个重要的用途:
一是解决了人们和机器之间的字符交互问题。每个字符不再是一个个抽象的文字、符号或图形,而是变成了一个个的数字,每个数字对应一个唯一的字符,而每个字符也有一个唯一的数字,两者之间是一一对应关系,而且不同字符和不同数字都各不相同,避免了“重名重姓”问题。这里,提到的表示字符的数字,我们也称之为 码点 ,后面我们还会详细介绍。
二是解决了不用语言国家字符集编码不统一的问题,提供了一个统一的编码方式,避免“各自为政,政出多门”的问题,方便相互之间的数据交流。
有了基本概念,那么我们看看Unicode字符集是如何实现对所有字符编码的。根据官网公布的Unicode 最新版本(9.0)介绍,Unicode字符集现在共包括 128,172***隐藏网址***
那Unicode字符集怎么解决这个编码问题呢?它采用的是“分块编码”。按照国籍、地区、用途、功能等不同属性,把字符先进行分类,然后再根据每个小字符类的字符个数,确定一个个大小不同的 码块 ,下面节选了几种字符及其对应的 码点 。
(节选)
0000..007F; Basic Latin(基本拉丁字母)
4E00..9FFF; CJK Unified Ideographs(CJK统一表意文字)
1D100..1D1FF; Musical Symbols(音乐符号)
100000..10FFFF; Supplementary Private Use Area-B(补充专用区域-B)
注意,“0000”、“007F”、“1D100”以及“100000”等,都是十六进制,这是每个字符在Unicode字符集中的编号,也就是相当于每个字符的“学号”。
可以看出,要表示一个字符,最长需要6位十六进制数,换算一下就是24位二进制数;而短的,比如基本拉丁字母,前面的“0”省去,只要2位十六进制(8位二进制数)就行了。
有了字符集,下面就要谈谈如何表示和使用这些字符(码点)了。毕竟,谁也不会闲了没事把字符编个号就为了练自己认字和数数的能力。 最重要的当然是为了让不同信息受体间交换信息 。
于是,就出现了UTF。所谓UTF是Unicode Transformation Format的缩写,意为Unicode转换格式。UTF具体分为3类,分别是UTF-32,UTF-16和UTF-8。
先看UTF-32。UTF-32是 定长编码 ,也就是说每个字符的编码长度都是固定的,‘32‘是其所使用的二进制编码的位数,即: 32位 。但通常以字节数进行量化,所以32位对应的字节数为 4字节 。
我们的Unicode字符集每个字符的码点最长也就是24位,相当于3个字节,而UTF-32给了4个字节(32位)来表示,给了字符集非常大的扩展空间(有兴趣的童鞋可以算算32位二进制数最大可以表示多大的数,这个数基本就对应了可以表示多少字符)。
没这时间计算这些的童鞋你就简单理解为,UTF-32就是一个“运超大箱”的快递公司,不管你寄什么,它都统一拿装冰箱的盒子寄(觉得不够大的,自行脑补一个),保证能一次装下你要寄的东西。
它的优点是被表示的Unicode字符都是固定长度的,易于查找和解码;但缺点是表示常用字符时内存占用太大,本地存储利用率或传输效率太低。
UTF-16是 变长编码 ,也就是说每个字符的编码长度是变化的,不是一成不变的。它的编码算法为:
在UTF-16中,2字节是字符的基本表示单元,低码点的用 2字节 表示,高码点的拆开后用 2个2字节 表示。
还是拿快递公司的例子类比,UTF-16是家提供了一种“运中等箱子”的快递公司,中等箱子能装下的就直接寄,装不下的,做个标记,分两个箱子寄,收件人需要特别注意下标记,如果没有标记,直接就用,如果有,就把两个箱子东西取出来拼起来后再用。
UTF-8也是 变长编码 ,它的编码算法与UTF-16并无本质区别,都是对Unicode进行分段,然后加上标识码,唯一的区别是分段更多。其算法如下:
在UTF-8中,1字节是字符的基本表示单元,最低的码点( 000000-0000FF )用1字节表示,高的码点( 000080-10FFFF )进一步分段,分别拆开为2个、3个和4个1字节。
可见,相比较而言,UTF-8是家只能“运小箱子”的快递公司,少数能装下的就用1个箱子运,不能装下的就拿2个、3个甚至4个来运。作为收件人,会非常辛苦的进行逐一判别,基本上都是需要拆箱组装后才能使用的(下面讲到也会有特例)。
当然,UTF-8在对于拉丁语系国家或者字符为主的信息传递和数据处理时,效率是非常高的,因为刚才Unicode字符集节选中提到的基本拉丁语范围刚好是 0000..007F ,在UTF-8中只要1个字节就够了。但是,对于中日韩(CJK,China-Japan-Korea)语系或字符为主的信息传递和数据处理时,效率就不那么好了,因为刚才节选的中日韩表意文字范围是 4E00..9FFF ,那在UTF-8中进行编解码时必须按照上面UTF-8算法的 第3条 进行处理,也就是要用 3个字节 来表示(还不如UTF-16的 2字节 ),所以国内很多中文数据较多的网站一般也不会采用UTF-8来进行编码,但作为程序猿还是比较喜欢用这种的编码方式。
完。
为什么MYSQL要设定用UTF8MB4编码UTF8MB4
MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes
4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。
二、内容描述
那上面说了既然utf8能够存下大部分中文汉字,那为什么还要使用utf8mb4呢? 原来mysql支持的 utf8
编码最大字符长度为 3 字节,如果遇到 4 字节的宽字符就会插入异常了。三个字节的 UTF-8 最大能编码的 Unicode 字符是
0xffff,也就是 Unicode 中的基本多文种平面(BMP)。也就是说,任何不在基本多文本平面的 Unicode字符,都无法使用
Mysql 的 utf8 字符集存储。包括 Emoji 表情(Emoji 是一种特殊的 Unicode 编码,常见于 ios 和 android
手机上),和很多不常用的汉字,以及任何新增的 Unicode 字符等等。
三、问题根源
最初的 UTF-8 格式使用一至六个字节,最大能编码 31 位字符。最新的 UTF-8 规范只使用一到四个字节,最大能编码21位,正好能够表示所有的 17个 Unicode 平面。
utf8 是 Mysql 中的一种字符集,只支持最长三个字节的 UTF-8字符,也就是 Unicode 中的基本多文本平面。
Mysql 中的 utf8 为什么只支持持最长三个字节的 UTF-8字符呢?我想了一下,可能是因为 Mysql
刚开始开发那会,Unicode 还没有辅助平面这一说呢。那时候,Unicode 委员会还做着 “65535
个字符足够全世界用了”的美梦。Mysql 中的字符串长度算的是字符数而非字节数,对于 CHAR 数据类型来说,需要为字符串保留足够的长。当使用
utf8 字符集时,需要保留的长度就是 utf8 最长字符长度乘以字符串长度,所以这里理所当然的限制了 utf8 最大长度为 3,比如
CHAR(100) Mysql 会保留 300字节长度。至于后续的版本为什么不对 4 字节长度的 UTF-8
字符提供支持,我想一个是为了向后兼容性的考虑,还有就是基本多文种平面之外的字符确实很少用到。
要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集,但只有 5.5.3
版本以后的才支持(查看版本: select version();)。我觉得,为了获取更好的兼容性,应该总是使用 utf8mb4 而非 utf8.
对于 CHAR 类型数据,utf8mb4 会多消耗一些空间,根据 Mysql 官方建议,使用 VARCHAR 替代 CHAR。
Unicode(utf-8) 是什么意思
8位Unicode转换格式(UTF-8)是一种用于编码各种字符的相对较新的代码约定。
它是字符标识的标准,也是各种编程语言和设备的参考,有助于标准化字母,数字和其他字符的显示。
在许多情况下,UTF-8取代了一种名为美国信息交换标准码(ASCII)的旧约定。
ASCII处理英语语言文本所需的所有字符,但UTF-8为不使用英语或罗马字母的其他语言处理更多不同的符号集。UTF-8被认为是与ASCII向后兼容的。
utf8 中 有占4字节的中文字符吗
***隐藏网址***
有关UTF-8的一些资料2008年06月13日 星期五 08:17一, 最重要的,UTF-8和Unicode的转换
UTF-8 编码是一种被广泛应用的编码,这种编码致力于把全球的语言纳入一个统一的编码,目前已经将几种亚洲语言纳入。UTF 代表 UCS Transformation Format.
UTF-8 采用变长度字节来表示字符,理论上最多可以到 6 个字节长度。UTF-8 编码兼容了 ASC II(0-127), 也就是说 UTF-8 对于 ASC II 字符的编码是和 ASC II 一样的。对于超过一个字节长度的字符,才用以下编码规范:
左边第一个字节1的个数表示这个字符编码字节的位数,例如两位字节字符编码样式为为:110xxxxx 10xxxxxx; 三位字节字符的编码样式为:1110xxxx 10xxxxxx 10xxxxxx.;以此类推,六位字节字符的编码样式为:1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx。 xxx 的值由字符编码的二进制表示的位填入。只用最短的那个足够表达一个字符编码的多字节串。例如:
Unicode 字符: 00 A9(版权符号) = 1010 1001, UTF-8 编码为:11000010 10101001 = 0x C2 0xA9; 字符 22 60 (不等于符号) = 0010 0010 0110 0000, UTF-8 编码为:11100010 10001001 10100000 = 0xE2 0x89 0xA0
以上转换例子已经确认是正确的,不用怀疑,如果看不懂请再仔细想想
Unicode编码和utf-8编码之间的对应关系表
The table below summarizes the format of these different octet types.
The letter x indicates bits available for encoding bits of the
character number.
Char. number range | UTF-8 octet sequence
(hexadecimal) | (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx //////A/////////
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
这是一个Unicode编码和utf-8编码之间的对应关系表。中文的Unicode编码范围在0000 0800-0000 FFFF 中。
二, 关于BOM
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?
Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:
在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。
这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
三, VB实现UTF-8转Unicode的函数
1.不使用API
Function Utf8ToUnicode(ByRef Utf() As Byte) As String
Dim utfLen As Long
utfLen = -1
On Error Resume Next
utfLen = UBound(Utf)
If utfLen = -1 Then Exit Function
On Error GoTo 0
Dim i As Long, j As Long, k As Long, N As Long
Dim B As Byte, cnt As Byte
Dim Buf() As String
ReDim Buf(utfLen)
i = 0
j = 0
Do While i 《= utfLen
B = Utf(i)
If (B And &HFC) = &HFC Then
cnt = 6
ElseIf (B And &HF8) = &HF8 Then
cnt = 5
ElseIf (B And &HF0) = &HF0 Then
cnt = 4
ElseIf (B And &HE0) = &HE0 Then
cnt = 3
ElseIf (B And &HC0) = &HC0 Then
cnt = 2
Else
cnt = 1
End If
If i + cnt - 1 》 utfLen Then
Buf(j) = "?"
Exit Do
End If
Select Case cnt
Case 2
N = B And &H1F
Case 3
N = B And &HF
Case 4
N = B And &H7
Case 5
N = B And &H3
Case 6
N = B And &H1
Case Else
Buf(j) = Chr(B)
GoTo Continued:
End Select
For k = 1 To cnt - 1
B = Utf(i + k)
N = N * &H40 + (B And &H3F)
Next
Buf(j) = ChrW(N)
Continued:
i = i + cnt
j = j + 1
Loop
Utf8ToUnicode = Join(Buf, "")
End Function
2. 使用API (包括Unicode转UTF-8)
Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByRef lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpDefaultChar As String, ByVal lpUsedDefaultChar As Long) As Long
Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Const CP_UTF8 = 65001
Function Utf8ToUnicode(ByRef Utf() As Byte) As String
Dim lRet As Long
Dim lLength As Long
Dim lBufferSize As Long
lLength = UBound(Utf) - LBound(Utf) + 1
If lLength 《= 0 Then Exit Function
lBufferSize = lLength * 2
Utf8ToUnicode = String$(lBufferSize, Chr(0))
lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(Utf(0)), lLength, StrPtr(Utf8ToUnicode), lBufferSize)
If lRet 《》 0 Then
Utf8ToUnicode = Left(Utf8ToUnicode, lRet)
End If
End Function
Function UnicodeToUtf8(ByVal UCS As String) As Byte()
Dim lLength As Long
Dim lBufferSize As Long
Dim lResult As Long
Dim abUTF8() As Byte
lLength = Len(UCS)
If lLength = 0 Then Exit Function
lBufferSize = lLength * 3 + 1
ReDim abUTF8(lBufferSize - 1)
lResult = WideCharToMultiByte(CP_UTF8, 0, StrPtr(UCS), lLength, abUTF8(0), lBufferSize, vbNullString, 0)
If lResult 《》 0 Then
lResult = lResult - 1
ReDim Preserve abUTF8(lResult)
UnicodeToUtf8 = abUTF8
End If
End Function
Private Sub Command1_Click()
Dim byt() As Byte
byt = UnicodeToUtf8("测试")
Debug.Print Hex(byt(0)) & Hex(byt(1)) & Hex(byt(2))
Debug.Print Utf8ToUnicode(byt())
End Sub
***隐藏网址***
utf-8的数字,英文,中文各自占用几个byte字节
文章总结: UTF-8字符编码的优势非常明显, 英文和数字(也就是ASCII字符集)还是只用一个byte, 而欧洲语言比如希腊语的字符占用2个byte, 中文占用3个byte.
英文字母和中文汉字在不同字符集编码下的字节数
英文字母:
·字节数 : 1;编码:GB2312
字节数 : 1;编码:GBK
字节数 : 1;编码:GB18030
字节数 : 1;编码:ISO-8859-1
字节数 : 1;编码:UTF-8
字节数 : 4;编码:UTF-16
字节数 : 2;编码:UTF-16BE
字节数 : 2;编码:UTF-16LE
中文汉字:
字节数 : 2;编码:GB2312
字节数 : 2;编码:GBK
字节数 : 2;编码:GB18030
字节数 : 1;编码:ISO-8859-1
字节数 : 3;编码:UTF-8
字节数 : 4;编码:UTF-16
字节数 : 2;编码:UTF-16BE
字节数 : 2;编码:UTF-16LE
美国人首先对其英文字符进行了编码,也就是最早的ascii码,用一个字节的低7位来表示英文的128个字符,高1位统一为0;
后来欧洲人发现你这128位哪够用,比如法国人字母上面的还有注音符,这个怎么区分,于是把高1位编进来吧,这样欧洲普遍使用一个全字节进行编码,最多可表示256位。
但是即使位数少,不同国家地区用不同的字符编码,虽然0–127表示的符号是一样的,但是128–255这一段的解释完全乱套了,即使2进制完全一样,表示的字符完全不一样,比如135在法语,希伯来语,俄语编码中完全是不同的符号;
更麻烦的是,这编码传到中国后,中国人发现我们有10万多个汉字,你们欧美这256字塞牙缝都不够。于是就发明了GB2312这些汉字编码,典型的用2个字节来表示绝大部分的常用汉字,最多可以表示65536个汉字字符,这样就不难理解有些汉字你在新华字典里查得到,但是电脑上如果不处理一下你是显示不出来的了吧。
这下各用各的字符集编码,这世界咋统一?俄国人发封email给中国人,两边字符集编码不同,尼玛显示都是乱码啊。为了统一,于是就发明了unicode,将世界上所有的符号都纳入其中,每一个符号都给予一个独一无二的编码,现在unicode可以容纳100多万个符号,每个符号的编码都不一样,这下可统一了,所有语言都可以互通,一个网页页面里可以同时显示各国文字。
然而,unicode虽然统一了全世界字符的二进制编码,但没有规定如何存储啊。x86和amd体系结构的电脑小端序和大端序都分不清,别提计算机如何识别到底是unicode还是acsii了。如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,文本文件的大小会因此大出二三倍,这对于存储来说是极大的浪费。这样导致一个后果:出现了Unicode的多种存储方式。
互联网的兴起,网页上要显示各种字符,必须统一。 utf-8就是Unicode最重要的实现方式之一 。另外还有utf-16、utf-32等。 UTF-8不是固定字长编码的,而是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。 这是种比较巧妙的设计,如果一个字节的第一位是0,则这个字节单独就是一个字符; 如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。 (Google的 Protobuf也参考了这个设计)
注意unicode的字符编码和utf-8的存储编码表示是不同的,例如”严”字的Unicode码是4E25,UTF-8编码是E4B8A5,这个7里面解释了的,UTF-8编码不仅考虑了编码,还考虑了存储, E4B8A5是在存储识别编码的基础上塞进了4E25。
UTF-8 使用一至四个字节为每个字符编码。128 个 ASCII 字符(Unicode 范围由 U+0000 至 U+007F)只需一个字节,带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及马尔代夫语(Unicode 范围由 U+0080 至 U+07FF)需要二个字节,其他基本多文种平面(BMP)中的字符(CJK属于此类-Qieqie注)使用三个字节,其他 Unicode 辅助平面的字符使用四字节编码。
所以知道utf-8的中文是一个字符占几个字节了吧?当然是3个了啦!!!

更多文章:
全球新冠肺炎疫情背景下航运发展(盐田港复苏日志:半年历劫从“低谷”到“爆仓” 疫情之后巨轮如何越洋航行)
2026年9月7日 17:10
matlab求解带字母参数方程组(我想matlab求一个关于x,y的方程组 ab c d f e h m n 都是参数)
2026年9月7日 16:30
oracle中的循环语句(下面哪个不是oracle程序设计中的循环语句 a for)
2026年9月7日 15:30
电脑里2个系统怎么删除一个(电脑开机显示有两个系统,如何删除一个)
2026年9月7日 12:20
scrollthrough意思(“scroll”是什么意思)
2026年9月7日 08:00
怎么激活keygen(注册机如何激活cad2008一个简单激活cad2008的方法)
2026年9月7日 06:30





