varchar汉字占几个字符_字符编码笔记

198f4e84bdb01359a865c54b43e0f285.png

 前言 

2af0d18e72ea7ee625bcd87662f04264.png

相信不少同学在开发的过程中都会碰到过字符乱码的问题。

文件打开的字符编码格式不对,或者返参解析的编码格式不一致都有可能造成乱码问题。

而我们熟悉且常用的字符编码格式有这么几个: ASCII、GBK、Unicode、UTF8

但是我们真的了解这些字符编码?为什么会有这么多种类型字符编码,统一用一种不就好了吗?他们之间又有什么联系?(灵魂三连问)

efad006b1be451dae511d3b987a67dd9.gif

而肥壕也是只知其然,而不知其所以然,所以决定一探究竟。

198f4e84bdb01359a865c54b43e0f285.png

 正文

2af0d18e72ea7ee625bcd87662f04264.png

ASCII

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本延伸美国标准信息交换码则可以部分支持其他西欧语言,并等同于国际标准[ISO/IEC 646]。

简单说,就是把英文字母、数字符号与二进制之间做了一套统一的规定。ASCII 一共定义了128个字符的编码,用一个字节表示,但只占用了一个字节的后 7 位,最高位统一规定为 0。

GB

国家标准代码,简称国标码,是中华人民共和国的中文常用汉字编码集,亦为新加坡采用。

目前中华人民共和国官方强制使用 GB 18030–2005 标准,但 GB 2312–80 仍然在部分领域被使用。

强制标准冠以 GB。推荐标准冠以 GB/T。国家标准化指导性技术文件冠以 GB/Z

GB2312:(又称 GB1)是第一个修订的汉字编码字符集,每个汉字占两字节,收录了 6,763 个汉字。 GBK:由于中文博大精深,6763个大小无法覆盖所需的汉字,于是 GBK 兼容 GB2312 和 ASCII 的前提下扩展到了 21,003 个汉字。 GB18030:然而两万多字也没法满足咱们汉字的需求,两字节最多表示 65536个汉字,因此 GB18030 决定多出来的汉字使用四字节来表示,于是又在 GBK 的基础上扩展到了 70,244 个汉字。

Unicode

Unicode,中文又称万国码、国际码、统一码、单一码,是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。 很显然,不同国家都有各自的语言和编码,甚至对同一个文件如果写入和打开的编码格式不一致,也会导致乱码的出现。 为了解决这个问题,雄心勃勃的 Unicode 就此出现,誓要把世界上所有的符号都统一编码规范。 Unicode 的目的很简单:将全世界所有的字符统一在一个集合里,每个符号都有唯一的编码,再也不会出现乱码的问题。使计算机实现跨语言,跨平台的文本转换及处理。 Unicode 目前还不断在扩增,目前最新的版本为2020年3月公布的13.0.0,已经收录超过 13万 个字符。 但是有这么一个问题,Unicode 只是一个字符集,定义了符号的二进制代码,但是没有规定存储的格式。 比如“汉”字,Unicode 十六进制是 0x6c49 ,二进制数是是15位数 (110110001001001) ,表示至少需要2个字节。对于后面更大的字符,可能就需要 3 个字节或者 4 个字节,甚至更多字节来表示。 所以就会存在两个问题: 1. 如何区别 Unicode 和 ASCII ?计算机怎么知道 3 个字节表示一个符号,而不是分别表示 3 个符号呢? 2. 我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用 3 个或 4 个字节表示,那么每个英文字母前都必然有 2- 3 个字节是`0`,这对于存储来说是极大的浪费,文本文件的大小会因此大出 2 - 3 倍,这是无法接受的。

为了解决这存储格式不一致的问题,我们就需要有一个统一的格式,而下面的 UTF-8 就是其中的一个实现方式

UTF-8

UTF(Unicode Transformation Format,称为Unicode转换格式)
UTF-8(8-bit Unicode Transformation Format)是一种针对 Unicode 的可变长度字符编码 ,也是一种前缀码 。它可以用一至四个字节对Unicode字符集中的所有有效编码点进行编码,属于Unicode 标准的一部分。 UTF-8 是 Unicode 的实现方式之一,也是目前互联网上使用最广的一种实现方式。它的最大特点是可变长度编码,根据不同的符号使用 1-4 字节字符来表示。

UTF-8 的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为`0`,后面 7 位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。

2)对于`n`字节的符号(`n > 1`),第一个字节的前 `n` 位都设为`1`,第 `n + 1` 位设为`0`,后面字节的前两位一律设为`10`。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。依次从后往前填充。

代码范围UTF-8注释
000000 - 00007F  0xxxxxxx(00-7F)128个
000080 - 0007FF

110xxxxx(C0-DF) 10yyyyyy(80-BF)

1920个

000800 - 00D7FF

00E000 - 00FFFF

1110xxxx(E0-EF) 10yyyyyy 10zzzzzz

61440个
010000 - 10FFFF

11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz

1048576个
如果能够大概理解上面的描述和表格的规则,解读 UTF-8 还是应该比较容易的。 如果字符的第一位是 0 ,就说明这个单字节字符;如果第一位是 1 的话,就看最高位连续有多少个 1 就是多少个字节了 。

举个例子:

字符 A ,ASCII 二进制是 01000001 ,Unicode 二进制是 00000000 01000001 十六进制是 41,根据上表规则可知在第一个范围内,所以是单字节字符对应的 UTF-8 的编码也很容易得出来  01000001。 字符 中,Unicode 二进制是 01001110 00101101  十六进制是 9b2d  十进制是 39725,对应上表可知在第三个范围内,所以需要三个字节表示,我们只要往模板 1110xxxx(E0-EF) 10yyyyyy 10zzzzzz 将 unicode 的字符依次往后填充即可 11100100 10111000 10101101 当然还有其他实现方式比如 UTF-16(使用 2 或 4 字节表示)、UTF-32(使用 4 字节表示),这里就不仔细详述,大概了解一下就好了。

参考资料:

维基百科

https://zh.wikipedia.org/wiki

字符编码笔记:ASCII,Unicode 和 UTF-8

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

程序员必备:彻底弄懂常见的7种中文字符编码 

https://zhuanlan.zhihu.com/p/46216008

‍‍‍‍‍‍普通的改变,将改变普通 我是肥壕,一个在互联网低调前行的小青年 48166c6d9b57f0c526b095c8b208bcf9.png

6c7d7cb5fd86732cac7ffaa3af4f9cc5.png

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页