计算机编码:ASCII,Unicode 和 UTF-8
-
计算机编码
计算机最小存储单元为bit(位),有0、1两种状态,最小运算单元为Byte(字节),1 Byte = 8 * bit 。那么1Byte就有256种二进制状态,可以代表256种字符。如果规定好人们现实生活中的字符与数量(number)的映射关系那么即可将人类语言存储在计算机硬件上。
-
ASCII
ASSCII 是一个美国制定的映射标准。规定了 英文字符 <-> 数字 <->二进制表示 之间的关系。即可以将英文字符映射到byte上,ASSCII共规定了128个字符,正好使用1byte的后7个bit。第一位统一规定为0
例如:空格
SPACE
是32(二进制00100000
) 大写的字母
A
是65(二进制01000001
) 由于世界上不单单是只有英文,所以也需要定义汉字,日文,拉丁文等多种符号集,每个国家都在ASCII基础上定义了自己的编码标准,将闲置的最高位利用起来可以表示256个字符,像汉字都是上万的字符,单字节不够,就需要用到第二个字节。但不管怎样每个国家的标准都是独自的,像130在法语编码中代表了
é
,在希伯来语编码中却代表了字母Gimel
(ג
),这就导致了乱码的发生,所以出现了一个大一统的标准,Unicode -
Unicode
将世界上主要符号都进行与数字的映射,一个符号对应唯一一个数学数字(通常用十六进制表示),由于范围太大以至于对应的数字用二进制表示时,需要2个3个甚至4个字节。例如ucs-2 (unicode的一种实现方式,分为大小端两种)固定用两个字节表示一个字符,那么计算机每次都读取两个字节来存储字符,记录一个简单字符时例如数字3,只用到了1个字节,那么后1个字节补零,这对计算机空间是一种浪费,所以需要一种以Unicode映射关系为基准又能根据字符动态调整占用空间的编码。现在互联网主要标准为utf-8。
-
UTF-8
由上述可知Unicode不适合做存储与数据传输(空间浪费,带宽浪费),而utf-8实现了一种将unicode规定的字符根据所占用字节数动态存储机制。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
,就表示当前字符占用多少个字节‘严’的 Unicode 是
4E25
(100111000100101
),根据上表,可以发现4E25
处在第三行的范围内(0000 0800 - 0000 FFFF
),因此严
的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx
。然后,从严
的最后一个二进制位开始,依次从后向前填入格式中的x
,多出的位补0
。这样就得到了,严
的 UTF-8 编码是11100100 10111000 10100101
,转换成十六进制就是`E4B8A5另外一个utf-8编码的文件可以在文件头用
EF BB BF
表示这是UTF-8编码,后面紧跟数据,这样的utf8编码叫带BOM(byte-order mark)的utf-8格式。 -
ucs-2、ANSI
-
ANSI
是默认的编码方式。对于英文文件是ASCII
编码,对于简体中文文件是GB2312
编码(只针对 Windows 简体中文版,如果是繁体中文版会采用 Big5 码) -
ucs-2
也是一种unicode的编码方式,固定用两个字节存储字符的Unicode十六进制。根据两个字节前后顺序分大端(Big endian) 、小端(Little endian)以汉字
严
为例,Unicode 码是4E25
,需要用两个字节存储,一个字节是4E
,另一个字节是25
-
Big endian 时 :4E 25
-
Little endian时:25 4E
那么 计算机怎么知道某一个文件到底采用哪一种方式编码?
Unicode 规范定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做"零宽度非换行空格"(zero width no-break space),用
FEFF
表示。这正好是两个字节,而且FF
比FE
大1
。如果一个文本文件的头两个字节是
FE FF
,就表示该文件采用大头方式;如果头两个字节是FF FE
,就表示该文件采用小头方式。记事本另存为 可实现转换。
-
-
参考:
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html