[十]基础数据类型之Unicode编码简介
2018-10-11 13:34
351 查看
编码含义
关于编码的含义,之前也说过,计算机只能存储二进制序列 所以对于字符,保存的时候,需要进行编码为二进制,进行存储 呈现的时候,需要将二进制进行解码,转换成字符的形式 有很多种编码方式,比如ASCII (American Standard Code for Information Interchange,美国信息交换标准代码) 使用一个字节进行编码,一个字节可以表示的最大值为255 很显然,对于英语和其他一些西欧语言来说,足够了,英文字母总共才几个对吧 那么对于汉字呢?ASCII显然是不够用的,所以出现了GBK等以支持汉字 那么,日语 韩语呢?他们当然也搞出来一些支持他们文字的编码Unicode诞生
于是,人们意识到他们应该提出一种标准方案来展示世界上所有语言中的所有字符,出于这个目的,Unicode诞生了 Unicode 是一种字符集,规定了符号对应的二进制代码 至于这个二进制代码如何存储则没有任何规定,也就是说它是一种编码规定 是编码字符集,而不是实际的编码方案 最初Unicode使用一个16位长度的二进制序列,也就是最多支持 (2的16次方-1) 65536个字符,也就是0 ~ 65535 范围是 0x0000 ~0xFFFF Unicode使用U+前缀, 加上编码的值,来表示Unicode中的字符编码 也就是 U+0000 ~ U+FFFFUnicode不够用了
显然,随着更多字符的增加, 65536 是不够用的 于是Unicode 不得不进行扩展,于是使用8位用作扩展位,形式如下 一个字节8位可以表示 2的8次方-1 = 256 个数,最大可以扩展为 256 *65526=16777216 个 不过也不需要那么多的字符, 仅仅使用了前面的17个 也就是00 01 02 03 04 05 06 07 08 0A 0B 0C 0D 0E 0F 10 |
于是按照扩展位,划分了17个维度,这每个维度,叫做一个平面 17个平面,编号从 0~16 |
每个平面 65536个字符 |
17个平面,扩展后总共可以表示1114112个字符 |
扩展后的范围为 U+000000 ~ U+10FFFF |
编码方式
Unicode 没有规定字符对应的二进制码在计算机中如何存储,只是规定了他的值是多少而已 一个字符对应的实际的值,我们称之为代码点 code point 那么一个码点实际的值怎么存储呢? 可能需要1个,可能需要2个,甚至可能需要3个或者4个字节来表示 对于计算机来说,面对着一堆字节,他们知道到底哪个或者哪几个是一个字符呢?听起来可能有点迷惑,不是知道具体的值了么?怎么还不知道如何表示? 比如数字1 他的码点是1 假如我用两个字节来存储,每个字节的前两位我当做其他的标志位, 设置为11 那么可能结果是这样子的11000000 11000001 显然,他的值并不是1 编码方式只是可以保证,你的字符是按照指定的字符集进行编码的 也就是说如果你告诉我拿出来码点为1 的,我会把1100 0000 1100 0001 解析成数字1 但是并不能保证我保存的数据就是他的码点的真值,0000 0001 ,中间形式是编码方式说了算的 最直观的例子就是网络中报文的传输,都会附加自己的头信息 所以中间传输的数据并不是跟你发送的数据一模一样,中间的数据就是编码形式的存储 但是,接收端接受解析后,就是跟你发送的数据一样的,这就好像是你的字符 |
UTF-8 是变长 UTF-32 是定长 UTF-16介于他们之间 2个字节或者4个字节 |
utf-16
UTF-16编码以16位无符号整数为单位 |
我们把Unicode编码记作U 编码规则如下 如果U<0x010000, 也就是0x000000 ~ 0x00FFFF U的UTF-16编码, 就是U对应的16位无符号整数 |
如果U≥0x010000 也就是0x010000 ~ 0x10FFFF 我们先计算下 U'=U-0x010000 可以得出来 U' 范围是 0x000000 ~ 0x0FFFFF 显然, U'的最大值为0xFFFFF 也就是最多20个1 也就是可以被写成20个二进制位 既然是20个二进制位,那么我们是不是可以把它拆分成两组呢? 每组10个二进制位 00 0000 0000 它能表示的范围是2的10次方=1024个 BMP是2个字节,16位, 很显然,如果把U' 拆分成两组,每组10个二进制位的话 每一个都能够保存到2个字节内 所以Unicode标准规定:基本多语言平面内,U+D800..U+DFFF的值不对应于任何字符,为代理区 ,其中又分为高代理区和低代理区 U+D800 加上10个二进制位的数值的最大值,可以得到高代理区的范围 U+D800 --->1101 10 00 0000 0000 + 0000 00 11 1111 1111 = 1101 1011 1111 1111 = 0xDBFF 下一个就是0xDBFF +1 = 0xDC00,所以低代理区从0xDC00 开始 0xDC00 加上10个二进制位的数值的最大值,可以得到低代理区的范围 0xDC00----> 1101 1100 0000 0000 + 0000 00 11 1111 1111 = 1101111111111111 = 0xDFFF |
高代理区范围 U+D800 ~0xDBFF 低代理区范围 0xDC00 ~ 0xDFFF 代理区间是U+D800....U+DFFF |
所以UTF-16的编码方式就是 先计算 U'=U-0x010000 然后将U'写成二进制形式:yyyy yyyy yyxx xxxx xxxx 然后分别计算高位代理和低位代理 U+D800 --->1101 10 00 0000 0000 + 0000 00 yy yyyy yyyy = 1101 10 yy yyyy yyyy 0xDC00----> 1101 1100 0000 0000 + 0000 00 xx xxxx xxxx = 1101 11xx xxxx xxxx |
再精简下步骤 1. 先计算 U'=U-0x010000 2. 然后将U'写成二进制形式:yyyy yyyy yyxx xxxx xxxx 3.两个值为 1101 10 yy yyyy yyyy / 1101 11xx xxxx xxxx |
之前我们提到过,Unicode中的一个字符的值,被称之为一个码点 显然,一个码点,可能被一个代码单元存储,也可能被两个连续的代码单元存储 |
UTF-32
UTF-32编码以32位无符号整数为单位 Unicode的UTF-32编码就是其对应的32位无符号整数 32位可以表示的个数为 2的32次方 为4294967296,显然绰绰有余,没什么好说的了UTF-8
UTF-8 是目前互联网上使用最广泛的一种 Unicode 编码方式,可变长 使用 1 - 4 个字节表示一个字符,根据字符的不同变换长度字节序
根据我们上面描述的utf8 以及utf16都有可能使用不止一个字节进行编码 其实还有很多其他数据也不仅仅是一个字节进行表达 在计算机中最终都是二进制序列的形式 比如utf-16中,虽然我可以根据值确定是否在0号平面内,还是在扩展辅助平面的 但是,如何把一个二进制序列解析为他的值,这是一个问题 比如 0000 0001 0000 0010 假如说这是一个十六进制数 他到底表示的是0102 还是0201? 从哪边开始解读? 人会很自然的把左边当高位,右边当低位, 但是, 计算机, 你必须对他进行说明 这就是字节序的问题 其实就是高位和低位与内存地址高低的对应关系 分为大端排序( Big endian BE)和小端排序(Little endian LE) 大端排序----高地址存储低位 低地址存储高位 小端排序----高地址存储高位 低地址存储低位在内存中0x01020304的存储方式 内存地址 4000 4001 4002 4003 BE 01 02 03 04 LE 04 03 02 01 |
相关文章推荐
- J2SE基础篇——数据类型、执行过程、进制、编码
- Python【基础:数据类型和变量 字符串和编码 list和tuple 条件判断 循环 dict和set】注意事项(与java,c比较)
- VS2008中unicode编码的数据类型转…
- python 输出JSON类型数据时遇到的编码问题(utf8,unicode)
- ANS.1编码详解(一)----基础语法和数据类型
- Java基础之Java简介、变量、数据类型、运算符及其相关配置
- java成长之路1-1(java简介、基础数据类型、运算符)
- c++转码基础(1):各种编码类型及unicode和uft-8互转
- 【Swift】学习笔记(一)——熟知 基础数据类型,编码风格,元组,主张
- Python入门(二)——IDE选择PyCharm,输入和输出,基础规范,数据类型和变量,常量,字符串和编码,格式化
- 编码-字符集-基础数据类型
- Python基础知识-数据类型和变量,字符和编码及格式化
- Lua语法基础(1)---简介、基本数据类型、表达式
- 黑马程序员——Java基础---数据类型、编码解码
- J2SE基础篇——数据类型、运算符、语句、程序执行时内存分配、进制、编码
- iOS基础篇之——helloword工程搭建及基本数据类型简介
- Python3学习(一)-基础、数据类型、变量、字符串和编码、list&tuple、if、for、while、dict、set、函数与参数
- MySQL基础笔记(一) SQL简介+数据类型
- TypeScript 基础数据类型简介
- MySQL基础笔记(一) SQL简介+数据类型