Ascll、Ansi、Unicode、UTF8
在计算中,所有的东西都是0和1.
就看设计者规定这些0和1代表什么意义。
到底是一段声音,还是像素点拼合成的图片,或者很多图片和声音拼合的电影,程序,文字。
关键看怎么样去理解规定。
为了让不同的电脑可以交换信息。
1967年,美国国家标准学会制定了信息交换标准代码。
说穿了,让做显卡的厂家输出字符的时候,大伙把标准统一一下。
就跟安卓系统一样,虽然有小米改版的安卓系统,也有魅族改版的,锤子手机,三星手机,华为手机。
各有自己的特点,但总不能我的APP,在你上面不能运行吧?那就不好玩了。
秦始皇统一货币一个道理。
Ascll用一个1字节来表示。
一个字节是8位。
表示范围:0000 0000 -1111 1111
换句话说有256种可能性,可以代表256个不同的符号。
但科学家只使用了里面的低7位
表示范围:0000 0000 - 0111 1111 美国人占了
1000 0000 -1111 1111
所以,最初的Ascll码可以表示128个不同的符号。
ASCII码一共规定了128个字符的编码,比如空格”SPACE”是32(二进制00100000),
大写的字母A是65(二进制01000001)。
这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。
英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。比如,在法语中,字母上方有注音符号,它就无法用ASCII码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。
但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。
比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (?),
在俄语编码中又会代表另一个符号。
但是不管怎样,所有这些编码方式中,0–127表示的符号是一样的,不一样的只是128–255的这一段。
至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。
一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。
比如,简体中文常见的编码方式是GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示256×256=65536个符号。
不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。
不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
ANSI编码表示英文字符时用一个字节,表示中文用两个或四个字节。
世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。
可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是Unicode (统一码、万国码、单一码),就像它的名字都表示的,这是一种所有符号的编码。
Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,0639表示阿拉伯字母Ain,0041表示英语的大写字母A,4E25表示汉字”严”。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表。
要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
比如,汉字”严”的unicode是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。
这里就有两个严重的问题,第一个问题是,如何才能区别Unicode和ASCII?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。
它们造成的结果是:1)出现了Unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示Unicode。2)Unicode在很长一段时间内无法推广,直到互联网的出现。
互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
下表总结了编码规则,字母x表示可用编码的位。
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
——————–+———————————————
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
跟据上表,解读UTF-8编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
下面,还是以汉字”严”为例,演示如何实现UTF-8编码。
已知”严”的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此”严”的UTF-8编码需要三个字节,即格式是”1110xxxx 10xxxxxx 10xxxxxx”。然后,从”严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,”严”的UTF-8编码是”11100100 10111000 10100101″,转换成十六进制就是E4B8A5。
是不是看的很头疼,上面的那些话不需要你全明白,知道大概意思就可以,不会有人死记硬背吧?
当然除了上面这些,将来我们还会见到其他编码。
比如GB2312以及GBK。
以后用的时候,讲吧,不然这些东西太无聊了。
只需知道,是一些人为了让计算机存储不同的汉字或者其他国家的文字而设计的一种对应数字以及在内存的存储方式。
ASCII值 | 16进制 | 控制字符 | ASCII值 | 16进制 | 控制字符 |
0 | 00H | NUT | 32 | 20H | (space) |
1 | 01H | SOH | 33 | 21H | ! |
2 | 02H | STX | 34 | 22H | ” |
3 | 03H | ETX | 35 | 23H | # |
4 | 04H | EOT | 36 | 24H | $ |
5 | 05H | ENQ | 37 | 25H | % |
6 | 06H | ACK | 38 | 26H | & |
7 | 07H | BEL | 39 | 27H | , |
8 | 08H | BS | 40 | 28H | ( |
9 | 09H | HT | 41 | 29H | ) |
10 | 0AH | LF | 42 | 2AH | * |
11 | 0BH | VT | 43 | 2BH | + |
12 | 0CH | FF | 44 | 2CH | , |
13 | 0DH | CR | 45 | 2DH | - |
14 | 0EH | SO | 46 | 2EH | . |
15 | 0FH | SI | 47 | 2FH | / |
16 | 10H | DLE | 48 | 30H | 0 |
17 | 11H | DCI | 49 | 31H | 1 |
18 | 12H | DC2 | 50 | 32H | 2 |
19 | 13H | DC3 | 51 | 33H | 3 |
20 | 14H | DC4 | 52 | 34H | 4 |
21 | 15H | NAK | 53 | 35H | 5 |
22 | 16H | SYN | 54 | 36H | 6 |
23 | 17H | TB | 55 | 37H | 7 |
24 | 18H | CAN | 56 | 38H | 8 |
25 | 19H | EM | 57 | 39H | 9 |
26 | 1AH | SUB | 58 | 3AH | : |
27 | 1BH | ESC | 59 | 3BH | ; |
28 | 1CH | FS | 60 | 3CH | < |
29 | 1DH | GS | 61 | 3DH | = |
30 | 1EH | RS | 62 | 3EH | > |
31 | 1FH | US | 63 | 3FH | ? |
NUL | VT 垂直制表 | SYN 空转同步 |
SOH 标题开始 | FF 走纸控制 | ETB 信息组传送结束 |
STX 正文开始 | CR 回车 | CAN 作废 |
ETX 正文结束 | SO 移位输出 | EM 纸尽 |
EOY 传输结束 | SI 移位输入 | SUB 换置 |
ENQ 询问字符 | DLE 空格 | ESC 换码 |
ACK 承认 | DC1 设备控制1 | FS 文字分隔符 |
BEL 报警 | DC2 设备控制2 | GS 组分隔符 |
BS 退一格 | DC3 设备控制3 | RS 记录分隔符 |
HT 横向列表 | DC4 设备控制4 | US 单元分隔符 |
LF 换行 | NAK 否定 | DEL 删除 |
ASCII值 | 16进制 | 控制字符 | ASCII值 | 16进制 | 控制字符 |
64 | 40H | @ | 96 | 60H | 、 |
65 | 41H | A | 97 | 61H | a |
66 | 42H | B | 98 | 62H | b |
67 | 43H | C | 99 | 63H | c |
68 | 44H | D | 100 | 64H | d |
69 | 45H | E | 101 | 65H | e |
70 | 46H | F | 102 | 66H | f |
71 | 47H | G | 103 | 67H | g |
72 | 48H | H | 104 | 68H | h |
73 | 49H | I | 105 | 69H | i |
74 | 4AH | J | 106 | 6AH | j |
75 | 4BH | K | 107 | 6BH | k |
76 | 4CH | L | 108 | 6CH | l |
77 | 4DH | M | 109 | 6DH | m |
78 | 4EH | N | 110 | 6EH | n |
79 | 4FH | O | 111 | 6FH | o |
80 | 50H | P | 112 | 70H | p |
81 | 51H | Q | 113 | 71H | q |
82 | 52H | R | 114 | 72H | r |
83 | 53H | X | 115 | 73H | s |
84 | 54H | T | 116 | 74H | t |
85 | 55H | U | 117 | 75H | u |
86 | 56H | V | 118 | 76H | v |
87 | 57H | W | 119 | 77H | w |
88 | 58H | X | 120 | 78H | x |
89 | 59H | Y | 121 | 79H | y |
90 | 5AH | Z | 122 | 7AH | z |
91 | 5BH | [ | 123 | 7BH | { |
92 | 5CH | / | 124 | 7CH | | |
93 | 5DH | ] | 125 | 7DH | } |
94 | 5EH | ^ | 126 | 7EH | ~ |
95 | 5FH | — | 127 | 7FH | DEL |