编码方式的简介

1. ASCII

ASCII是7比特的字符集,涵盖了英语中的绝大多数字符。编码从0到127.

2. ISOLatin-1(the ISO-8859-1 standard)

ISO Latin-1是8比特的字符集,定义了256个字符。前128个字符(00000000-01111111)与ASCII完全一致。

3. Unicode

Unicode只是定义了字符的编码值,并未指定值以何种形式存储。比如汉字“田”的Unicode编码是16进制的7530,转换为二进制是01110101,00110000。比方现在定义一种unicode的实现方式UTF-FAKE,规则是

a.      使用24个字节

b.      每个字节的高7位都是1

c.      每个字节的最末一位存储unicode编码值

那么01110101,00110000的存储形式是

11111110, 11111110, 11111110, 11111110, 11111110, 11111110, 11111110, 11111110,

11111110, 11111111, 11111111, 11111111, 11111110, 11111111, 11111110, 11111111,

11111110, 11111110, 11111111, 11111111, 11111110, 11111110, 11111110, 11111110

其中末位为蓝色0的字节为补足字节。

实际使用的编码方式UTF-8使用三个字节存储“田” 01110101,00110000,如下

11100111, 10010100, 10110000

Unicode的第一个版本于1991年发布,该版本允许的的最大编码空间是两个字节。96年发布的Unicode 2.0版本引入了surrogate pair,将Unicode的编码数目扩充到了百万级,由于可见的将来该数目不大可能用光,因此Unicode委员会对外宣称该上限永不会更改。Surrogate pair在UTF-16和UTF-32中得到了实现。Unicode的前256个字符及编码值与Latin-1完全一致。比如大写字母A在Latin-1和Unicode中的编码值都是0x41(十进制的65)。

Unicode的编码值范围是 000000hex 10FFFFhex,可划分为17个plane,每个plane包含65536(= 216)个字符。Plane的代码从0到16(十进制),对应于 000000hex010000hex020000hex… …0F0000hex10FFFFhex的蓝色部分。

Unicode的表示方式一般是”U+”后缀上4到6个十六进制字符,如”田“的Unicode表示方式是U+7530。

4. UTF-8

UTF-8采用可变长度的编码,长度从1到4个字节不等。某些应用识别非标准的"utf8" 或"UTF 8"别名。只有ASCII字符在UTF-8中使用一个字节编码,且值与ASCII完全相同,其余字符在UTF-8中使用2到4个字节。因此UTF-8中的单字节且只有单字节编码字符的最高的1个比特是0。

UTF-8对Unicode字符的编码规则如下

Bits of
code point

First
code point

Last
code point

Bytes in
sequence

Byte 1

Byte 2

Byte 3

Byte 4

  7

U+0000

U+007F

1

0xxxxxxx

11

U+0080

U+07FF

2

110xxxxx

10xxxxxx

16

U+0800

U+FFFF

3

1110xxxx

10xxxxxx

10xxxxxx

21

U+10000

U+1FFFFF

4

11110xxx

10xxxxxx

10xxxxxx

10xxxxxx

说明如下:

1.   只有ASCII使用单字节编码

2.   Unicode编码值大于127的字符使用多个字节编码。多字节序列的第一个字节称为leading byte,后续的字节称为continuation bytes。Leading byte的高位是110,1110或11110,其中的“1”的个数标明了序列中的字节总数。如2个字节序列的leading byte为110xxxxx,其中的11标明了这是一个双字节的序列,亦即该序列有1个continuation byte。Continuation bytes的每个字节的高两位均是10

3.  单字节序列、leading bytes和continuationbytes的高位分别是0,110/1110/11110和10,因此不会混淆。

还是以汉字”田“为例,展示Unicode字符如何按照UTF-8存储。”田“的Unicode值是U+7530,比对上表发现介于U+0800 - U+FFFF之间,因此需要3个字节来存储。7530转为二进制是1110101,00110000,一共15位。但由于UTF-8的3字节编码存储16个比特,因此将1110101,00110000的高一位补零变成16比特01110101,00110000。然后将这16比特依次填入三字节序列1110xxxx 10xxxxxx 10xxxxxx的x中,得到结果

11100111 10010100 10110000,写成16进制就是E7 94 B0

注意:虽然Unicode中的前256个字符及编码值与Latin-1完全一致,但UTF-8只对前128个即ASCII字符采用单字节编码,其余128个Latin-1字符是采用2个字节编码。因此ASCII编码的文件可以直接以UTF-8方式读取,而Latin-1的文件若包含值为128-255的字符则不可以。

5. UTF-16

UTF-16也是采用可变长度编码,可以是一个或者两个16比特。某些应用中允许使用非标准的UTF_16或者UTF16作为别名。Unicode中的第一个plane的65536(= 216)codepoints采用16比特编码,其余的16个plane均采用2个16比特编码。采用2个16比特编码的前后两个16bit分别称为lead surrogate pair和trail surrogate pair,之所以称为surrogate是因为单独一个16bit不代表任何字符,只有组合起来才有意义。

既然UTF-16也是可变长度编码,如何区分某个16bit是单独表示一个字符还是与后续的16bit组合起来表示一个字符呢?Unicode将D800–DBFF和DC00–DFFF这两个范围作为保留区间,没有将之分配给任何Unicode字符,若某16比特落在D800–DBFF范围内,便可将之视为采用2个16bit编码字符的第一个16bit,而落在DC00–DFFF的16bit可视为采用2个16bit编码字符的第二个16bit。这就使得Unicode第一个plane实际可分配使用的code points只有65536 – (DFFF - D800 + 1) = 65536 – 8*256 = 63488。

采用一个16bit编码的Unicode字符在UTF-16中的编码值与其在Unicode中是相等的,比如英文大写字母A的Unicode值是U+0041,其UTF-16编码是0041 hex 。Unicode第二到第十七个plane采用两个16bit即surrogate pairs的字符从其Unicode code point到UTF-16的转换规则是

1.  范围为0x10000 … 0x10FFFF的codepoint减去0x010000,减过后的结果范围是0x00000到0xFFFFF,使得该结果可以使用5位16进制亦即20位2进制数表示

2.  结果中高10位(范围是0x0到0x3FF)加上0xD800(结果范围是0xD800到0xDBFF)作为双16bit的第一个16bit即leadsurrogate

3.  结果中低10位(范围是0x0到0x3FF)加上0xDC00(结果范围是0xDC00到0xDFFF)作为双16bit的第二个16bit即trailsurrogate

这样UTF-16与UTF-8都是self-synchronizing的,即某个16bit是否是一个字符的开始无需检查其前一个或者后一个16bit。与UTF-8的不同之处是,UTF-16不支持从某个随机的字节开始读取。

举例:UTF-16 序列 0041, D801DC01 (字符"A"),若第一个字节丢失即从第二个字节读取,那么UTF-16认为序列是41D8,01DC,01;而UTF-8不存在这个问题。

BOM(byte-order mark)

BOM是Unicode中用来标识字节顺序的字符。

对于UTF16和UTF32,由于编码单元分别是16bit和32bit,即2个和4个字节,编码单元内字节的顺序就取决于计算机的体系结构。以英文大写字母A和汉字田为例,大端(big endianness,缩写为BE)和小端(littleendianness,缩写为LE)存储的字节序列是

UTF-16BE

UTF-16LE

UTF-32BE

UTF-32BE

A

00,41

41,00

00,00,00,41

41,00,00,00

75,30

30,75

00,00,75,30

30,75,00,00

BOM就是用来标识编码使用的是大端还是小端存储,该符号位于文本序列起始字节之前。

UTF-8

UTF-8中的BOM是 0xEF,0xBB,0xBF。Unicode标准里面允许UTF-8使用BOM,但并不要求也不鼓励使用。由于UTF8编码单位是字节,字节的先后顺序在编码、传输和解码过程中均不改变,因此不存在endianness。BOM在UTF8中的唯一作用是标识序列使用的是UTF8编码,在由其它使用BOM的编码转换为UTF8编码的情况下,建议在UTF8序列中保留BOM以便转换回原编码的时候不丢失BOM信息。

接下来看看用Notepad++的HEX-Editor插件查看的文件16进制的编码。

文件中仅包含一个英文大写字母A,其Unicode编码值是U+0041。

使用UTF-8(缺省包含BOM),字节序列是ef bb bf 41

使用不带BOM的UTF-8,字节序列是 41。

UTF-16

UTF-16中bigendianness和littleendianness的BOM分别是U+FEFF和U+FFFE。可以使用编码方式UTF-16BE和UTF-16LE来显式地标明字节顺序,当使用了UTF-16BE和UTF-16LE时,BOM不应该再出现在字节序列中,很多应用直接忽略该字符若其仍然存在。

由于Notepad++不支持UTF16编码,因此下面的截图中使用了UTF-16的前身UCS-2来替代。UCS-2对Unicode的第一个plane的编码与UTF-16相同,都是1个16bit,且编码结果相同。

UTF-32

UTF32中的bigendianness和littleendianness的BOM分别是0000FEFF和FFFE0000。

总结五种编码方式的BOM依次是

BOM

编码方式

00 00 FE FF

UTF-32, big-endian

FF FE 00 00

UTF-32, little-endian

FE FF

UTF-16, big-endian

FF FE

UTF-16, little-endian

EF BB BF

UTF-8

编码方式的简介(ASCII, LATIN-1, UTF-8/16/32)相关推荐

  1. java ascii 编码方式_JAVA 的ASCII字符编码一览表

    JAVA 的ASCII字符编码一览表 二进制 十进制 十六进制 缩写 可以显示的表示法 名称/意义 0000 0000 0 00 NUL ␀ 空字符(Null) 0000 0001 1 01 SOH ...

  2. HTTP 头部的编码方式——ASCII编码

    先说结果,http请求行.响应行的编码方式都为ASCII,这也是为什么需要对url进行url编码,将非ASCII字符转为ASCII字符. 我们知道在HTTP头部中传入的信息不会被url encode, ...

  3. java字符编码方式总结

    java字符编码方式总结一.概要在JAVA应用程序特别是基于WEB的程序中,经常遇到字符的编码问题.为了防止出现乱码,首先需要了解JAVA是如何处理字符的,这样就可以有目的地在输入/输出环节中增加必要 ...

  4. 【转】刨根究底字符编码之十一——UTF-8编码方式与字节序标记BOM

    一.UTF-8编码方式 1. 接下来将分别介绍Unicode字符集的三种编码方式:UTF-8.UTF-16.UTF-32.这里先介绍应用最为广泛的UTF-8. 为满足基于ASCII.面向字节的字符处理 ...

  5. 【转】Unicode 及编码方式概述

    背景概述 我们都知道计算机是不能直接存储字母,数字,图片,符号等,计算机能处理和工作的唯一单位是"比特位(bit)",一个比特位通常只有 0 和 1,是(yes)和否(no),真( ...

  6. 常见三种字符编码的区别:ASCII、Unicode、UTF-8

    什么是字符编码? 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255( ...

  7. 【转】刨根究底字符编码之十三——UTF-16编码方式

    1. UTF-16编码方式源于UCS-2(Universal Character Set coded in 2 octets.2-byte Universal Character Set).而UCS- ...

  8. 如何使mysql编码格式_Mysql设置编码方式及基本操作

    介绍 Mysql 默认安装后的编码方式默认一般是Latin, 在插入汉字数据或读取的时候,存在乱码或报错.这时候,只需要修改编码方式为UTF8,统一数据库和数据表的编码方式. 如何修改 1. 复制My ...

  9. python中的编码方式

    说明 这里我们以python2.7为例讲解python的编码方式 指定执行编码方式 python2.7的默认编码方式为ascii字符集,这里所说的编码方式指执行编码方式,在编程过程中,有三个地方都涉及 ...

最新文章

  1. 独家 | 我们扒出了这家中国创业公司,竟比苹果iPhone X早两年推出黑科技,还不用借助深度摄像头
  2. 【并行编程】系统体系结构和组件具体说明
  3. env export set 作用
  4. 怎样编写一个Photoshop滤镜(1)
  5. 从jHiccup开始
  6. 艾创机器人_世界教育机器人大赛 2019赛季世界锦标赛落幕曲靖代表队获多个奖项...
  7. 二级计算机vf题型,2010计算机等级考试二级VF考试题型与解题技巧
  8. 蓝桥杯 基础练习 龟兔赛跑预测
  9. javascript 闭包和原型
  10. 三极管的使用方法,放大,截止,饱和
  11. 游程编码解密(C语言详解)
  12. 机器学习:训练集和测试集
  13. dumprep 0 -k引起的重启问题
  14. proposal中文翻译_proposal是什么意思_ proposal的翻译_音标_读音_用法_例句_爱词霸在线词典...
  15. 【学术】 一个博士的经历(小木虫精华帖,留着细细体会!)
  16. iphone12 fiddler抓包,代理证书无法下载解决
  17. iOS上应用如何兼容32位系统和64位系统
  18. 【正点原子FPGA连载】第三十六章 基于OV5640的PL以太网视频传输实验-摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0
  19. 发送邮件服务器错误怎么更改,邮件发不出去 服务器错误550怎么解决?
  20. UI控件之Button(按钮)和ImageButton(图像按钮)

热门文章

  1. IBM励志微电影--《成为你》
  2. 俄展示第六代战机项目:具备人工智能!
  3. 强推!30个遥感数据下载网站整理分享
  4. HTTP基础:请求报文
  5. windows和linux加密u盘,linux怎样挂载windows分区和U盘
  6. ZooKeeper 相关概念总结
  7. 男女性别识别【目标检测+图像分类】数据集分享coco-voc
  8. 大一计算机学科导论作业
  9. 2017秋招京东Java工程师面经
  10. 构造形式化证明,解决智能合约安全问题——你的合约亟待证明