关于ASCII、ANSI、ISO 8859-1、GBK、Unicode 与 UTF 的探究与辨析

AUTHOR | nicechi
类别 | 知识储备
发表 | 2019-10-13 06:55:54
更新 | 2020-08-05 21:27:32

计算机有多种的字符编码标准,一般来说字符编码标准又可以分成编码方式与字符集。编码方式通过字符集中的每个字符所对应的唯一确定的值,然后转换成一个二进制序列供计算机使用。不同的编码方式可能会影响一个字符的字节长度,从而影响整个文件的大小。

使用不同的编码方式去读取一个文件,可能会出现乱码的现象,之所以说是“可能会出现”,是因为大多数字符集的前128位都继承了 ASCII,所以大小写英文字母和数字、以及一些经常使用的符号的编码结果基本上是一样的,这时候一般不会发生乱码现象。但是如中文符号等,因为不同的编码方式所使用的字符集不一样,所以就会出现乱码现象,可能一个字符在一个字符集中是一个意思,而在另一个字符集中却代表另一个意思。除此之外,编码所使用的字节长度上的不同策略也会造成乱码现象,比如说 UTF-8 分别可以使用一个、两个、三个或四个字节来编码一个字符,而 UTF-16 却只能使用两个、或四个字节来编码字符,所以可能一个字符在 UTF-8 中只需要一个字节来表示,但是使用 UTF-16 来解码的话,它可能读取两个字节来解析,所以这时候字符所代表的意思就发生了变化,也就造成乱码的现象。

什么是字符集(character set)

简单来说,字符集就是一系列可以被计算机硬件或软件所识别的字符的集合,在这个集合中的每一个字符都有一个唯一确定的值。

比如说最常见的 ASCII,此字符集中一共有128个字符,每一个字符都有一个唯一确定的值,例如 A 在 ASCII 中的值为 65,a 在 ASCII 中的值为 97.

什么是字符编码(character encoding)

计算机是无法直接显示或者存储字符的,它只能识别二进制数值。

所以字符编码(character encoding)就用来告诉计算机某个字符的二进制数值是多少(字符编码因不同的字符集而不同)。例如,可以简单认为 Unicode 为一个字符集,而 UTF-8、UTF-16 与 UTF-32 就是 Unicode 的字符编码方式。

在字符编码中,code point(代码点,有时也称之为 code position)指的就是一个字符在某个字符集中唯一确定的值。

什么是 ASCII 

ASCII即 American Standard Code for Information Interchange (美国信息交换标准代码)。

这里就出现了一个问题,ASCII 是一个字符集呢,还是一个字符编码呢? 

在 Wikipedia 上对于 ASCII 的定义为:" is a character encoding standard for electronic communication. " 它指出 ASCII 是一个用于电子通讯的字符编码标准。我更倾向于认为 ASCII 就是一套标准,它包含了编码部分与字符集部分,当然单纯地认为 ASCII 是一个字符集或者是一个字符编码也都可行,只要语境正确,能正确表达此时指的是字符集部分还是编码行为就行。

ASCII 字符长度为一个字节,但是它只用了 7-bit,也就是能表示128种符号(范围为0~127),其中0~31和值127指的是控制字符(control character),所谓控制符号就是不可在显示屏上显示的符号,它代表着某一种动作,例如值26所表示的 SUB 即代表 Ctrl+Z 的行为。除控制字符之外,其余的字符都为可显示字符(printable character)。

你可以使用 &#decimal_value (采用十进制的值)和 &#hex_value (采用十六进制的值)两种格式来将相对应的 ASCII 字符显示在网页上。例如 A 在 ASCII 中的值为 65,所以,你可以分别使用 A  或者 &#x41  来将 A 显示在HTML页面上。

因为其他字符编码标准,如 ANSI、ISO 8859-1、GBK 或者Unicode 等,其0~127也都采用了与ASCII一样的值,所以可以认为ASCII是其他字符编码标准的基础。

什么是 ANSI 

ANSI 原意为 American National Standards Institute(美国国家标准协会),但是在计算机技术中,它经常被用来代表一系列的字符集,因为它没有固定的字符集,因此也没有固定的编码方式。

ANSI 字符的长度为一个字节,其前 0~127 的值与 ASCII 一致,剩下的128个字符取决于要使用哪一种扩展,通常这个扩展取决于系统默认的 locale(即本地化,如不同国家支持不同的文字) 或者 codepage (即与特定字符集相关联的字符编码),这就解释了为什么 ANSI 没有固定的字符集。很多情况下会把 ANSI 称为 Windows-1252。

什么是 ISO 8859-1

ISO 8859-1 也是一种编码标准,它是由 ECMA(European Computer Manufacturers Association,欧洲计算机制造联合会)所开发的。

ISO 8859-1 的长度也为一个字节,其前 0~127 的值也与 ASCII 一致,剩下的128个字符大多是欧洲语言所使用的字符,所以可以认为 ISO 8859-1 就是为欧洲语言所定制的一套编码标准。一般来说,ISO 8859-1 也被称为 Latin 1

什么是 GBK 

GBK,即“国家标准扩展”的缩写,很明显它是我们国家的国标

同样,GBK 也兼容 ASCII ,GBK 字符的长度为一个字节或两个字节,当字符的值与 ASCII 的值相同的话(即前128个字符),长度为一个字节,其余的字符为两个字节。

GBK 是 GB2312 字符集(主要为简体中文)的扩展,如今,它不仅可以用来支持简体中文,还支持繁体中文、日文等其他文字。

什么是 Unicode 及什么是 UTF(UTF-8、UTF-16 和 UTF-32)

Unicode是一套统一的标准,包括对于文字的统一表示、编码和处理。其的出现就是为了解决 ANSI 、ISO 8859-1 和 GBK 及其他编码系统之间的互不兼容的问题。

Unicode 的编码系统最初所支持的是固定的16位(2个字节),即 U+0000 到 U+FFFF。但是现在为了支持更多的字符,编码的长度已经变成了 U+0000 到 U+10FFFF,这时候所支持的字符数量已经超过了一百万,那些值超过 U+FFFF 的字符又被称为 Supplementary(补充)。

Unicode 有多种的 encoding schemes(即编码方案),即所谓的 UTF(包括 UTF-8、UTF-16 和 UTF-32),此 encoding schemes 设计两方面的问题:1、一个字符需要使用几个字节来表示;2、怎样将每个字符所对应的值映射成二进制形式。

UTF,即 Unicode Transformation Format(Unicode 转换格式),每一种 UTF 都定义了一个算法用来映射每一个 Unicode 的 code point (即代码点,即每一个 Unicode 字符所对应的唯一值)成唯一的二进制序列。

UTF 通常分为:UTF-8、UTF-16 和 UTF-32 

UTF-8:最经常使用的UTF encoding scheme,它使用一个、两个、三个或四个字节来编码字符,像与 ASCII 相同的字符就使用一个字节。它的其中一个优点就是可以减少文件的大小,例如,在大多数情况下,它可以比 UTF-16 少使用 1.5 倍的空间。

UTF-16:它使用两个或者四个字节来编码字符,在 Java 的内部处理中,就是使用 UTF-16 来编码,这样的其中一个好处就是可以提高运行处理效率,因为它相对于 UTF-8 来说,它的字符长度不是两个字符就是四个字符,而 UTF-8 的字符长度变化太大,减少文件大小的代价就是降低处理效率。

UTF-32:它使用固定的四个字节来编码字符。

在 UTF 中还有一个概念,即 BOM(byte order mark,字节顺序标记)。通常情况下,一个文件可能在开头的时候就会带有 BOM,帮助 reader(读取器)检测当前文件使用的是哪一种 Unicode encoding schemes。

  • UTF-8 的 BOM :EF BB BF
  • UTF-16 的 BOM:FE FF
  • UTF-32 的 BOM:00 00 FE FF

注意:BOM 所使用到的字符也被计算在文件大小内

 

最后,希望这篇文章能带给你点启发,Have Fun!


CATEGORY

TOP