做者:shede333 html
主页:http://my.oschina.net/shede333 && http://blog.sina.com.cn/u/1509658847
版权声明:原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | [Creative Commons BY-NC-ND 3.0][] python
Unicode
20世纪80年代末,
位于美国加州的组织容许任何愿意支付会费的公司和我的加入,其成员包含了主要的电脑软硬件厂商,例如奥多比系统、苹果公司、惠普、IBM、微软、施乐等,
组成Unicode组织的商业机构
Unicode Consortium
,和国际合做的国际标准化组织
IEEE
由于电脑普及和信息国际化的前提下,分别各自成立了Unicode组织[2]和ISO-10646工做小组。他们不久便发现对方的存在,你们为着相同的目的而工做。
1991年,Unicode Consortium与ISO/IEC JTC1/SC2赞成保持Unicode码表与ISO 10646标准保持兼容并密切协调各自标准进一步的扩展。虽然实际上二者的字集编码相同,但实质上二者确实为两个不一样的标准。
ISO(或者叫
IEEE
)开发了
ISO/IEC 10646 标准,
通用字符集(Universal Character Set,UCS)是
ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集
两种标准字符集相互兼容,这两个组织各自发布的标准有点复杂,暂时还没彻底弄清楚
通用字符集
(Universal Character Set,UCS)
又称Universal Multiple-Octet Coded Character Set,
我的理解 ,咱通俗的说Unicode,
通用字符集UCS,其实都是一回事,都指的是Unicode字符集。
下面我就统一用 Unicode
ISO/IEC 10646标准 与 Unicode标准 之间的关系,以下图:

编码
编码方案,也叫实现方式,即把Unicode字符 以何种方式写到硬盘上。
一个字符的Unicode编码是肯定的。可是在实际传输过程当中,因为不一样
系统平台
的设计不必定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不一样。Unicode的实现方式称为
Unicode转换格式
(Unicode Transformation Format,简称为UTF)
UTF是“
Unicode Transformation Format”的缩写,能够翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。
而UTF8,UTF16,UTF32则是规定了Unicode字符按照指定的规则存储到硬盘上了,也按照一样的规则读出来,属于编码。
编码名字中的数字也表明必定的意思,UTF编码的数字标明每一个码点的bit数(我的理解:UTF-8最少8个位, UTF-16最少16位,UTF-32最少32位),UCS编码的数字表明每一个码值的字节数。
UCS-2用两个字节编码,UCS-4用4个字节编码。
UTF-8 和UTF-16是目前最通用的编码,web页面,网络传输主要用的是UTF-8,UCS相关的名称如今说的不多了。
UCS-2是UTF-16的子集,如今要是说UCS-2的话,基本上指的是UTF-16;
后面讲解UTF-16 和UTF-32是的时候,或详细讲解他们和UCS二、UCS4的区别
强调一下,Unicode只是一个抽象的标准而已,只作映射,不涉及到编码的存储策略,和密码本相似,属于字符集,指定了一个从字符到数字的映射;
Unicode的出现解决了在一篇文档里面出现多种语言的问题,在Unicode出现以前,每种字符集通常都是对应一种语言的。
Unicode能够被不一样的编码方式实现,例如UTF8,UTF16,
GB 18030
从这里能够很清楚地看到:
- 编码是依赖于字符集的,就像代码中的接口实现依赖于接口同样;
- 一个字符集能够有多个编码实现,就像一个接口能够有多个实现类同样。
注意:
一个【字节】是8位二进制,可表示为 0xFF,也可表示为 1111 1111
【字符】,每一个Unicode码位都是一个字符,“a”是一个字符,“王”也是一个字符,“😄”也是一个字符
UCS-4根据最高位为0的最高字节分红2
7=128 (2^7)个group。每一个group再根据次高字节 分为256 (2^8)个平面(plane)。每一个平面根据第3个字节分为256行 (row),每行有256个码位(cell)。
group 0的平面0被称做BMP(
Basic Multilingual Plane
)。group这个级别极少用
0x7F 0xFF 0xFF 0xFF
group plane row cell
若是UCS-4的前两个字节为全零,那么将UCS-4的BMP去掉前面的两个零字节就获得了UCS-2。
目前的
Unicode字符分为
17组,
0x0000 至 0x10 FFFF,共111 4112个。( int("0x10FFFF", 16) = 1114111 ),
有1,112,064个码位(code point)可用来映射字符(这和UCS-4是兼容的),
每组称为平面(Plane),而每平面拥有65536(2^16)个码位,
0号平面称为
BMP
(后面有详细的介绍BMP),承载了大部分经常使用字符,
其余16个平面(1~16)称为
辅助平面
(Supplementary Planes)
Unicode最大字符为 0x10 FFFF,那么能够理解为21位的编码方案( bin(0x10) == 0b10000, 21 = 5+4*4 )
虽然UCS-4的编码最大能够用31位,可是两者已经达成协议,即便新加的字符也会保证分配到前17个平面(0~16)内,即0x0 ~
0x10 FFFF这个范围,因此说两者能够说是一致的,后面我就仍是统一来Unicode这个名词来讲。
这可算是两者的定义区别吧,但实际上二者是兼容的。后面咱们只以Unicode为标准,编码方面以UTF来说。
每一个平面有2
16=65536 个码位。
Unicode计划使用了17个平面,一共有17×65536=111 4112个码位。
在Unicode 5.0.0版本中,
已定义的码位只有238605个(并不表明有这么多字符,只是说已经分配的,包括PUA等),分布在平面0、平面一、平面二、平面1四、平面1五、平面16。
虽然计划使用17个平面,但目前只有以下几个平面才被用。
其中平面15和平面16上只是定义了 两个各占
65534个码位的专用区(Private Use Area),分别是0xF0000-0xFFFF
D和0x100000-0x10FFF
D。所谓专用区,就是保留给你们放自定义字符的区域,能够简写为
PUA。
(后面有对PUA的详细介绍)
平面0也有一个PUA专用区:0xE000-0xF8FF,有6400个码位;
PUA区域不分配Unicode字符。
平面0的0xD800-0xDFFF,共2048个码位,是一个被称做代理区(Surrogate)的特殊区域,这个区域也不分配Unicode字符。
UTF-16就利用保留下来的0xD800-0xDFFF区段的码位来对辅助平面的字符的码位(BMP之外的字符
)进行编码。
在介绍UTF-16编码时会介绍。
如前所述在
Unicode 5.0.0版本中,
238605-65534*2-6400-2048=99089(删除平面1五、16,BMP平面上的PUA,BMP平面上的用于UTF-16的代理区)。余下的99089个已定义码位分布在平面0、平面一、平面2和平面 14上,它们对应着Unicode定义的99089个字符,其中包括71226个汉字。
平面0、平面一、平面2和平面14上分别定义了52080、 341九、43253和337个字符。
平面2的43253个字符都是汉字。平面0上定义了27973个汉字。
在表示一个Unicode的字符时,一般会用
“U+xxxx”而后紧接着一组十六进制的数字(
4~6位)来表示这一个字符。在
基本多文种平面(英文为
Basic Multilingual Plane,简写 BMP。它又简称为“零号平面”, plane 0)里的全部字符,要
用四位十六进制数(例如U+4AE0,共支持六万多个字符);
在BMP平面之外的字符则须要使用
五位或六位十六进制数了。
Unicode 到目前为止所定义的五个平面中(不包括1五、16的PUA平面),第0平面(BMP)最为重要,包含了绝大部分经常使用字符
例如,“汉字”对应的数字是0x6c49和0x5b57,而编码的程序数据是:
Basic Multilingual Plane(BMP)
BMP,
基本多文种平面,
又称为“零号平面”、plane 0, 包含了大部分的经常使用字符,然而,大部分的字符都分配给CJK了
BMP的字符的编码为
U+hhhh
,其中每一个
h
表明一个
十六进制
数字,与UCS-2编码彻底相同
其中 (U+D800–U+DBFF) 和 (U+DC00–U+DFFF) 码点被UTF-16占用了,因此这部分不分配任何字符。
65,392 of the 65,536 code points in this plane have been allocated to a
Unicode block, leaving just 144 code points in unallocated ranges
(64 code points at 0860..089F, 64 code points at 1C80..1CBF, and 16 code points at 2FE0..2FEF).
A map of the Basic Multilingual Plane. Each numbered box represents 256 code points.
Private Use Areas
在Unicode标准中,
Private Use Area
(
PUA
)范围内的字符不会被分配出去,
目前,PUA有3个区域:
- BMP平面的(U+E000–U+F8FF),
- planes 15 (U+F0000–U+FFFFD)
- planes 16 (U+100000–U+10FFFD)
在这3个区域内的字符不能被分配给Unicode字符。Unicode是故意不分配这部分区域,目的是其余的第三方机构可能会定义他们本身的字符,以此来避免与Unicode产生冲突
CJK
中日韩统一表意文字(CJK Unified Ideographs),目的是要把分别来自中文、日文、韩文、越文中,本质、意义相同、形状同样或稍异的表意文字(主要为汉字,但也有仿汉字如日本国字、韩国独有汉字、越南的
喃字)于ISO 10646及
Unicode标准内赋予相同编码。
CJK 是中文(Chinese)、日文(Japanese)、韩文(Korean)三国文字的缩写。顾名思义,它可以支持这三种文字。实际上,CJK 可以支持在 LaTeX 中使用包括中文、日文、韩文在内的多种亚洲双字节文字。
注:中、日、韩文字里面相同的字用的是同一个Unicode字符,这一点颇有争议,由于,虽然是同一个字,可是在不一样的语言里面应该是不一样的字形(字体),可是Unicode这样的规定就致使了没法给这个字符加上多种字体了。
做者:shede333 ios
主页:http://my.oschina.net/shede333 && http://blog.sina.com.cn/u/1509658847
版权声明:原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | [Creative Commons BY-NC-ND 3.0] web
UTF-8的特色是对不一样范围的字符使用不一样长度的编码。变长编码
对于0x00-0x7F之间的字符,UTF-8编码与
ASCII编码彻底相同。
UTF-8编码的
最大长度是6个字节。从下表能够看出,6个字节的模板有31个x,便可以容纳31位二进制数字。Unicode的最大码位0x7FFF FFFF也只有31位。
在这些编码中,性能最好,在绝大多少的网页中使用的都是UTF-8
注:bin(0x7FFFFFFF) = ‘0b1111111111111111111111111111111’ 这个31位2进制
注:中文范围 4E00-9FBF,也就是说每一个中文字符的UTF-8编码都是3个字节
注意:USC-4 的规定里,最大能够表示31位的字符,2^31 == 0x7FFF FFFF,UTF-8理论上能够所有表示出来,
实际中,咱们使用Unicode规定的17个平面(0x0~0x10 FFFF),由此可看出,UTF-8最多用
4个字节便可表示Unicode目前已分配的字符
测试:
文档存储“哈”这1个字,保存成utf-8格式(不带BOM),而后使用HexMiner来查看其真实内容:E59388
使用python查看 “哈”字的string存储内容 '\xe5\x93\x88’ ,和上面是一致的
UTF-16是
变长编码,UTF-16是UCS最第一版本的第一个修正案,是UCS-2的一个扩展,以此来表示BMP平面以外的码点
-------------
"Universal Character Set" (UCS)
在上世界80年代晚期,就开始了UCS计划,最开始时打算用2个字节(2^16==65536)来表明一个字符,
早期,
这种的两字节编码被称为“Unicode”,可是如今被称做“UCS-2”;
在指定Unicode的中早期,就发现65536字符(即两字节编码)是不够用的,IEEE就引进了UCS-4标准(即每一个字符须要4个字节来表示),可是这个决定却被
Unicode Consortium组织反对,反对的缘由有两个:
- 一个字符用4个字节表示会浪费硬盘和内存空间;
- 许多计算机制造商已经在UCS-2技术上投入了大量资金;
在发布Unicode 2.0版本的时候,UTF-16就被IEEE开发出来解决这两个组织的僵局。
---------
UTF-16编码以16位无符号整数为单位。咱们把Unicode编码记做U。编码规则以下:
如今定义一个新单位,定义2个字节(即16位)为一个Word,那么以上U<0x10000编码的的字符就是是一个Word;
若是U<0x10000,U的UTF-16编码就是U对应的16位无符号整数(为书写简便,下文将16位无符号整数记做WORD)。
若是U≥0x10000,咱们先计算U’=U - 0x10000,而后将U'写成二进制(5个字节)形式:yyyy yyyy yyxx xxxx xxxx,
那么U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。
按照上述规则,Unicode编码0x10000-0x10FFFF的UTF-16编码有两个WORD,第一个WORD的高6位是110110,第二个WORD的高6位是110111。可见,
第一个高位WORD的取值范围(二进制)是
1101 1000 0000 0000到
1101 1011 1111 1111,即
0xD800-0xDBFF。
第二个低位WORD的取值范围(二进制)是
1101 1100 0000 0000到
1101 1111 1111 1111,即
0xDC00-0xDFFF。
为了将一个WORD的UTF-16编码与两个WORD的UTF-16编码区分开来,Unicode编码的设计者将
0xD800-0xDFFF保留下来,并称为代理区(Surrogate):
由上所知:
当在一个 UTF-16 编码的字符串里发如今
0xD800-0xDFFF这个范围内的序列时,就能马上知道这是某个代理对的一部分
即在UTF-16中,对于U<0x10000的字符,UTF-16编码和Unicode编码都用两个字节表示,并且编码内容也相同;
对于U≥0x10000这部分字符,须要使用使用两个Word来表示(即4个字节),并且每一个Word的最高位被定死了,第一个Word的最高6位为110110, 第2个Word的最高6位为110111,
能够想象,之因此把两个Word的最高位定死,就是为了把这种两个Word表示一个字符的 和 一个Word表示一个字符的区分开,那么,若是第一个Word的110110******能够表示一个正常的Unicode字符的话,那么咱们就分不清110110******究竟是表示一个字符呢,仍是表示两个Word的高位。
注:在提出UTF-16以前(即UCS-2)上
0xD800-0xDFFF是有分配Unicode字符的,在推出UTF-16以后才把这部分的字符分配去掉的。
Example 1:
用十进制作一个例子,一开始要求要表示50个字符:
那么咱们规定用两位十进制来表示一个字符,这样咱们就能表示100个字符了(0~99),而咱们只用了前50个字符,后50个字符都还没分配;
而后来有需求变动了,须要表示的字符增长到了 120 个了,同时要求兼容以前的50个字符标准:
那么咱们规定,对于 0~79的字符 只能使用2位十进制,
十位只能使用0~7,
个位随意,这样就能用两位十进制表示80个字符;
对于大于80的字符,咱们使用2个十进制数(即4位)来表示一个字符,这两个十进制分为高位、低位,高位数的十位只能为8, 低位数的十位用9
对于小于80的数字 ,例如要表示数字12,那么就用 12 来表示
对于大于等于80的数字须要使用两个十进制数字表示,例如要表示数字80,那么就用 80 80,其他的表示方法以下
原始字符 编码后的表示方式
80 80 90
81 80 91
82 80 92
83 80 93
……..
90 81 90
91 81 91
92 81 92
……..
100 82 90
101 82 91
102 82 92
这样,当出现如下编码,咱们就知道表示什么意思了(忽略空格)
编码后(存在硬盘上的内容) 34
82 95 56
80 94
要表达的原始字符 34
105 56
84
Example 2:
我的理解:
下面只针对于UTF16大于0x10000部分,
因为目前Unicode的范围是0x0 ~ 0x10FFFF,BMP平面以外的字符范围是 0x1 0000 ~ 0x10 FFFF;
Unicode表示 0x10 FFFF个字符,那么须要21个bit位(bin(0x10) = 0b10000 即5位二进制,21 = 5+ 4*4),UTF-16须要把这些字符都表示出来
可是UTF16须要减去0x1 0000,那么就至关于 UTF16 用 0x0 ~ 0xF FFFF 去表示Unicode的 0x1 0000 ~ 0x10 FFFF,(0x10 FFFF - 0xF FFFF == 0x1 0000 )
这么看的话UTF16 只须要 表示0xF FFFF个字符便可,即20个bit位,那么咱们来算一下,UTF-16的这种2个Word能不能表示出来这20个bit位。
UTF16一个Word是两个字节(16个bit位),而后减去6个高位bit,那么一个Word的有效bit位是10,两个Word的有效bit位正好也是20,
这样看的话,UTF-16这种方法,用两个Word正好能够表示Unicode 大于0x1 0000的部分(BMP平面之外的部分)。
UTF-16,大部分字符使用
两个字节就能够表示,对于unicode的U≥0x10000,就要使用
四个字节了(即两个Word)。
建立一个文本,里面内容为“你好”,保存为 UTF-16 BE ,大端
那么文件的存储内容为
大端的BOM为 FEFF,你(\u4f60) 好(\u597d),这就明白上面的存储的内容了吧
最初,
ISO 10646
定义了31位编码标准,叫作UCS-4,UCS里的每个字符都是用32位码点表示(0 ~ 0x7FFF FFFF).
UCS-4是一个更大的还没有填充彻底的31位字符集,加上恒为0的首位,共需占据32位,即4字节。理论上最多能表示2
31
个字符,彻底能够涵盖一切语言所用的符号。
因为目前仅仅有17个平面在使用(0~0x10),全部的码点都在
0 and 0x10FFFF范围内,这就是UTF-32的编码范围,因此说,UTF-32是UCS-4的子集;
根据
JTC1/SC2/WG2规定,将来分配的新字符都被限制在 BMP平面(0 plane) 和前14 个平面内(1五、16平面只能用于PUA),这样UTF-32就能表示全部的Unicode字符,因此UCS-4和UTF32是一致的。
UTF-32编码以32位无符号整数为单位。Unicode的UTF-32编码就是其对应的32位无符号整数。
定长编码,4字节表示一个字符,并且UTF-32编码的值 和 Unicode标准的值一一对应,相对于其余变长编码,UTF-32的优势以下:
从编码值找到要表示的Unicode值是很快的,花费的时间是固定的,应为两者的值是同样的,而变长编码须要花费一些时间去作转换;
UTF-32最大的缺点:太浪费空间了,由于在文本里面,大部分都是BMP平面的字符
字节序:
字节序有两种,分别是“大端”(Big Endian, BE)和“小端”(Little Endian, LE)。
在UTF-16中,字节序是以
2个字节为单位的,在每一个单位内分
字节序(见下面高亮部分);
在UTF-32中,字节序是以
4个字节为单位的,在每一个单位内分
字节序。
根据字节序的不一样,UTF-16可被实现为UTF-16LE或UTF-16BE,UTF-32可被实现为UTF-32LE或UTF-32BE,以下图:
Unicode编码 |
UTF-16LE |
UTF-16BE |
UTF32-LE |
UTF32-BE |
0x6C49 |
49 6C |
6C 49 |
49 6C 00 00 |
00 00 6C 49 |
0x020C30 |
43 D8 30 DC |
D8 43 DC 30 |
30 0C 02 00 |
00 02 0C 30 |
BOM(Byte Order Mark)
字节序
Unicode标准建议用
BOM(Byte Order Mark)来区分字节序,即在传输字节流前,先传输被做为BOM的字符“零宽无中断空格”。
好比数字 12,最低有效位是个位数 1,通常来讲,内存地址都是从左到右递增,那么
小端的存储就是 2 1
大端的的存储是 1 2
以上同理能够应用到16进制表示法上。
在内存里存储字符串时,大多数实现方式天然都采用本身运行平台的 CPU 的字节序(endianness);而在硬盘里存储或者经过网络传输字符串时,UTF-16 容许在字符串的开头插入一个「字节序标记」(Byte Order Mask,BOM)
UTF-16 须要指明字节顺序,这也是为何 UTF-16 在文件格式和网络传输方面不受欢迎的一个缘由,不过微软和苹果都在本身的操做系统内部使用它。
下表是各类UTF编码的BOM:
UTF编码 |
Byte Order Mark (BOM) |
UTF-8 without BOM |
无 |
UTF-8 with BOM |
EF BB BF |
UTF-16LE |
FF FE |
UTF-16BE |
FE FF |
UTF-32LE |
FF FE 00 00 |
UTF-32BE |
00 00 FE FF |
由上所知:
UTF-32编码使用
4个字节
通常来讲,只有UTF-16 和UTF-32须要使用字节序,UTF-8不多须要,由于UTF-8就一种字节序,
使用python里的文件读取操做读取正常的UTF-8文件(没有BOM),
open(“文件路径”, “rb”).read() 便可得到内容
若是读取带有BOM的UTF-8文件,open(“文件路径”, “rb”).read() 获取的字符中,前几位会乱码,即BOM,若是这是一个json文件,那么一些json库就没法正确读取这些文件
要读取带有BOM的UTF-8文件,获取的内容又不带BOM,那么就要用
open(“文件路径”, “rb”).read().decode(“utf-8-sig")
Unicode In iOS
@"\U0001f604” 等同于字符 😄 ,当此字符串的长度 是
2
@"\u54c8” 等同于 @“哈” , 字符长度为1
就是说把BMP平面之外的字符长度当成2了
“
CFString 表明了一个 Unicode 字符组成的数组和一个字符总数的计数。……Unicode 标准定义了一个通用、统一的编码方案,其中每一个字符 16 位。”
这应该就是计算BMP平面之外字符的长度错误的缘由了吧,每一个字符16位是UCS-2那个时代的事情了
若是你很在乎长度的话,要解决计算长度计算错误,能够转为UTF32后再去计算啊,看样子UTF32也不是一无可取啊
NSString *s = @"\U0001F30D"; // earth globe emoji
NSLog(@"The length of %@ is %lu", s, [s length]); // 长度为 2
NSUInteger realLength = [s lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4; // realLength 为1
另外对 组合字符序列,变体序列的长度计算也是有问题的,这个就不能用UTF-32解决
例如 加剧音符号的e是“é”,é用Unicode表示的话须要两个字符组合起来,即小写e加剧音符号
NSString *s = @"e\u0301";
NSLog(@"%@,%d", s, s.length); // 输出 é,2
但实际上é对咱们来讲算一个字符的,长度应该为2,这种问题的处理方法也是有的,可是这里就不展开说明了,代码以下:
NSString *n = [s precomposedStringWithCanonicalMapping];
NSLog(@"The length of %@ is %lu", n, [n length]);
// => The length of é is 1
é既可使用上面说的组合方法表示,同时é其实也是单个Unicode字符"\u00e9"
NSString *s1 = @"\u00e9";
NSString *s2 = @"e\u0301";
NSLog(@"%@, %@, %d", s1, s2, [s1 isEqualToString:s2]); //输出结果: é, é, 0
s1,s2明明是同样的字符,可是isEqualToString方法去返回NO,这是由于NSString的“isEqualToString”方法只是一个个字节的比较,因此会得出不相等的结论
解决办法以下:
// Normalizing to form C
NSString *sNorm = [s precomposedStringWithCanonicalMapping];
NSString *tNorm = [t precomposedStringWithCanonicalMapping];
BOOL isEqualNorm = [sNorm isEqualToString:tNorm];
NSLog(@"%@ is %@ to %@", sNorm, isEqualNorm ? @"==" : @"!=", tNorm);
// 输出 é == é
Apple在PUA区域里面定义了一下字符(
文档点这里),虽然大多数已经再也不使用了,可是苹果的 logo 是个著名的例外:,它的码点是 U+F8FF。(你可能看到的是另外一个不一样的字符,这取决于你阅读本文的平台,理论上只有在Apple平台上才能看到这个字符)。
NSString 表明的是用 UTF-16 编码的文本,长度、索引和范围都基于 UTF-16 的码元。
我的理解:NSString之因此在BMP之外的字符长度计算错误,是为了保证快速的(时间复杂度 O(1) 级别)与 UTF-16 码元转换。
NSString 里面想要插入Unicode字符,可用以下方式:
BMP平面内(Unicode的码值 < 0x10000 ):@“\u266A”(♪)的方式输入,
最头上的u要小写,后面的其余字符不区分大小写
也可使用这种方式 @“\U0001F340”(🍀 )的方式输入(
最头上的U要大写),这种方式主要为BMP平面之外的部分用,固然,BMP平面内的也能够用
另外,C99 不容许标准 C 字符集里的字符用通用字符名(universal character name)来指定,所以不能这样写
NSString *s = @"\u0041"
我测试了一下,ASCII码的都不能用,后128位部分不能用。
这部分还没看完,待续~~~
ANSI编码
(American National Standards Institute),中文:美国国家标准学会。
不一样的国家和地区制定了不一样的标准,由此产生了 GB23十二、GBK、Big五、Shift_JIS 等各自的编码标准。这些使用 1 至 4 个字节来表明一个字符的各类汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操做系统中,ANSI 编码表明 GBK 编码;在日文Windows操做系统中,ANSI 编码表明 Shift_JIS 编码。 不一样 ANSI 编码之间互不兼容,当信息在国际间交流时,没法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。 固然对于ANSI编码而言,0x00~0x7F之间的字符,依旧是1个字节表明1个字符。这一点是ANSI编码与Unicode编码之间最大也最明显的区别。
ASCII
"Ascii"编码(American Standard Code for Information Interchange,美国信息互换标准代码)。
Unicode 额外介绍
再说一下,这些Unicode字符不是单独存在的,他们能够互相组合的,
例如,有重音符号的字母 é 能够直接表示成 U+00E9(「有尖音符号的小写拉丁字母 e」),或者也能够表示成由 U+0065(「小写拉丁字母 e」)再加 U+0301(「尖音符号」)组成的分解形式。这两个形式都是组合字符序列的变体;
再就是,许多看上去同样的字符都在不一样的码点编码了屡次,以此来表明不一样的含义。
注意:
1.百度百科上的介绍有些错误,更新也不及时,
强烈建议到Wiki上看资料
2.用Python查看UTF-8编码后的内容是没问题的,估计是由于UTF-8的每一个字节都是1开头的,越过了ASCII码,
而用查看UTF-16编码后的内容,有不少字符被解释成ASCII码后,就看不到原始内容了
3.使用
Python查看Unicode字符的一些方法,
想要查看某汉字的码点,好比查看 “好”字的码点:
"
好".decode("utf-8") //注意:后面的“utf-8”是平台的默认编码,若是你的平台默认编码不是utf-8的话,改你你当前平台的默认编码便可。
想要查看某码点表明的字符,例如查看“U+597d”这个码点表明的字符:
print u"\u597d" 或者
print u"\U0000597d”;
4位16进制数字(
\u597d)的表示方法:小写的u ,加“\” ,加 4位Unicode的16进制的码点;
8位16进制数字(
\U0000597d)的表示方法:大写的U ,加“\” ,加 8位Unicode的16进制的码点;
对于小于0x1 0000的字符(BMP平面内的),4和和8位的表示方法均可以;
对于大于等于0x1 0000之外的字符,必须使用8位16进制数字表示方法。
4.上面引用的一些图片,想要查看出处,点击图片便可。
工具:
- Hex Friend
- File Info Professional
参考:
注意,下面的中文文档并非英文版的翻译,两者不太相关,但英文版的介绍更丰富,建议看看英文版的
另外:
对字符编码感兴趣的话,推荐看下如下的文章: