字符集、字符编码、数据类型占字节数
文章目录
一、基本类型占字节数
- C语言:与操作系统的位数和编译器(不同编译器支持的位数可能有所不同)都有关
- Java语言:跨平台特性,数据类型占字节数固定。
二、字符集和编码集
字符编码笔记:ASCII,Unicode 和 UTF-8
图说我对Unicode的几点理解
编码方式 | 英文(字节数) | 中文(字节数) |
---|---|---|
GB2312 | 1 | 2 |
GBK | 1 | 2 |
ISO-8859-1 | 1 | 1 |
UTF-8 | 1 | 3、4 |
UTF-16 | 2(+2) | 2、4(+2) |
UTF-16BE | 2 | 2 |
UTF-16LE | 2 | 2 |
2.1、Unicode
Unicode(统一码、万国码、单一码)是计算机科学领域里一项业界标准。它对世界上的大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。Unicode为每一个符号指定一个独一无二的编码。
Unicode目前的编码范围为0x000000~0x10FFFF,并将该范围分为17个平面,每个平面拥有65536(2^16)个码位,共1114112个,但是目前只用了少数的几个平面。其中最重要的一个平面为平面0(Basic Multilingual Plane,简称BMP),该平面的编码范围为0x0000~0xFFFF,包含了世界上常用的语言文字和符号,是Unicode最基础和常用的部分。
2.2、UTF-8
UTF-8使用1~4个字节表示一个符号,不同的符号所占的字节数不同,所以UTF-8也称为可变长编码。
UFT-8的编码方式很简单,只有两条:
- 对于单个字节,字节的第一位为0,剩下的7位为该符号的unicode码。对于英文字母来说,其UTF-8编码和ASCII编码相同。
- 对于长度为n(n >1)的字节,第一个字节的前n位都为1,第n+1位为0。接下来的字节,每个字节的前两位均为10。剩下的位数使用该符号unicode码的二进制填充。
Unicode编码范围(16进制) | UTF-8编码(2进制) | 表示范围 |
---|---|---|
0x0000 0000~0x0000 007F | 0xxxxxxx | 2的7次方(128) |
0x0000 0080~0x0000 07FF | 110xxxxx 10xxxxxx | 2的11次方(2048) |
0x0000 0800~0x0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx | 2的16次方(65536) |
0x0001 0000~0x0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | 2的21次方(2 097 152) |
根据上表编码规则很容易对UTF-8进行解读。如果第一位为0,则该单个字节就表示一个字符;如果第一位为1,则有多少连续的1就表示该字符占几个字节。
现在以“中文”的“中”为例,“中”的unicode码为4E2D(100111000101101)属于上表中的第三行范围,所以”中”的UTF-8编码应该占3个字节(1110xxxx 10xxxxxx 10xxxxxx),用“中”的unicode码的二进制位进行填充,不足的位用0补齐。所以“中”的UTF-8编码为E4 B8 AD(11100100 10111000 10101101)。
2.3、UTF-16
UTF-16使用2-4个字节进行编码。
- 位于BMP(范围0x0000~0xFFFF)中的符号,UTF-16编码可直接使用该字符的unicode码直接表示,这时UTF-16编码占2个字节。
- 位于BMP外的符号,如果需要用UTF-16编码表示,需要将unicode码转换为四个字节的代理对(surroagte pair)来表示。
2.4、UTF-32
UTF-32 是固定长度的编码,始终占用 4 个字节,足以容纳所有的 Unicode 字符,所以直接存储 Unicode 编号即可,不需要任何编码转换。浪费了空间,提高了效率。
2.5、Little endian和Big endian
Unicode码可以采用UCS-2格式直接存储。
以汉字”严”为例,Unicode码是4E25,需要用两个字节存储,一个字节是4E,另一个字节是25。
- UTF-16BE (Big endian):存储的时候,4E在前,25在后
- UTF-16LE (Little endian):存储的时候,25在前,4E在后
Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做”零宽度非换行空格”(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。
UTF-16没有确定是大头方式,还是小头方式,所以文件头会多两个字节(FE FF 或者 FF FE)
- 如果一个文本文件的头两个字节是FE FF,就表示该文件采用大头方式。
- 如果一个文本文件的头两个字节是FF FE,就表示该文件采用小头方式。
2.6、ISO-8859-1
属于单字节编码,最多能表示的字符范围是0-255,应用于英文,无法表示中文。
2.7、GB2312/GBK
汉字的国标码,专门用来表示汉字,是双字节编码,而英文字母和iso8859-1一致(兼容iso8859-1编码)。其中gbk编码能够用来同时表示繁体字和简体字,而gb2312只能表示简体字,gbk是兼容gb2312编码的。