2.6. ANSI字符编码

2.6.1. ANSI是啥

ANSI,本身是American National Standards Institute的缩写,中文翻译为美国国家标准学会

ANSI是个非营利组织,其负责制定美国国家标准。

2.6.2. ANSI编码规则

ANSI字符编码的规则,或者是其所包含的字符的由来,主要是:

  1. 0-127 (0x00-0x7F)

    完全和7位编码的ASCII字符集(ASA X3.4-1963)相同

  2. 128-159 (0x80-0x9F)

    一些可打印字符

    这部分的编码,与国际编码ISO 8859-1的做法不同,ISO 8859-1是将此部分编码用于控制字符

  3. 160-255 (0xA0-0FF)

    参考了ISO 8859-1中的字符

由此可以看出,ANSI中很多字符,和ISO-8859中的字符,看起来非常相似。

这就导致了很多人误以为,ANSI和ISO-8859是一回事呢。

总结:

ANSI

= Windows Code Page 1252

= Windows Codepage 1252

= Windows 1252

= CP 1252

= 共256个字符

= 0-127的ASCII + 128-159的可打印字符 + 160-255的和ISO 8859-1中类似的字符

2.6.3. ANSI (Windows 1252)编码表

关于ANSI(Windows 1252)编码表格,可以参考:

[17]

[32]

2.6.4. ANSI编码与ANSI的关系

既然ANSI负责制定美国的国标,而在计算机方面,由于计算机最早是从美国最开始发展的,相应的所用到的字符编码方面,ANSI也制定了对应的标准,所以就叫做ANSI字符编码/ANSI字符集,英文为ANSI Code/ANSI Encoding/ANSI set/ANSI charset

2.6.5. ANSI字符编码和Windows 1252

Windows为了支持英语和西欧字符,自己设计了一个编码,对应的在Code Page号是1252,被称为Windows 1252。

Windows 1252的设计,是参考了ANSI草案(ANSI Draft)。

而ANSI draft后来发展成为正式的国际标准:ISO 8859-1

即,Windows 1252是在其成为正式标准ISO 8859-1之前而设计的,因此很容易理解,Windows 1252和ISO 8859-1不是完全等同的。

下面就来简要说说两者的区别。

2.6.5.1. Windows 1252和ISO 8859-1之间的区别

Windows 1252和ISO 8859-1基本等同

有点不同的是,在128-159(0x80-0x9F)的范围的值,ISO 8859-1编码为控制字符,而微软编码为可打印字符。

[提示] Windows 1252 vs. ANSI
  1. 类似Windows的Code Page为何被误称为ANSI Code Page,Windows 1252也被误称为ANSI编码,所以此处也可以说是ANSI编码和ISO 8859-1之间的区别。
  2. 而由于ISO 8859-1对应的Latin-1的西欧语言,所以此处也可以称为ANSI编码和ISO Latin-1之间的区别,比如[16]
  3. 微软的此种变体,有各种叫法:ANSI/Windows-1252/Windows Latin-1

    甚至有些微软的程序将其叫做Western European (Windows)。

    更有甚至,由于不清楚,而错称其为ASCII

[注意] 包含Lattin-1的内容在Notepad中显示乱码

因此,如果你把包含了128-159范围内的ISO Latin-1编码的文件,用Windows的记事本Notepad去另存为为ANSI的话,则会导致文件内容被错误处理了。

因为本身的那些128-159的字符,是控制字符,但是却被Notepad识别为可打印的字符了。

总之,对于Windows 1252,目前的各种叫法,可以理解为:

ANSI = Windows 1252 = CP 1252 = Windows code page 1252 = Windows Latin-1

2.6.6. 为何"ANSI编码"(在Windows中)被称为"本地编码"

先说一下本地编码,所谓本地编码,即当前Windows中的二进制的值,用何种编码去解析,然后显示出对应的该编码中的字符。

即,当然系统使用什么类型的编码。

而ANSI编码,根据前面内容得知,只是一个普通的对应于Windows 1252的一个编码而已。并不是其他某些编码合集的总称。

但是有时候,却又看到有人把ANSI编码解释为“本地编码”,比如[19]

其意思,就是[27]中所说的,Windows code pages有时又被称为"active code pages","system active code pages"。

而作为微软用A表示ANSI版本的函数,W表示Wide,Unicode版本的函数,此时所有的A版本的函数,就都用的是当前有效的Code Page,即"本地编码"了

其中,Windows系统中,当前有且只有一个active Windows code page。

也就意味着,此处所谓的ANSI编码,就相当于之前所说的Code Page了,即当前系统采用何种编码去解析字符

也就是你当前系统中设置的本地编码为何种编码,然后系统中,遇到需要解析的字符,就按照你所设置的本地编码去解析了。

比如,本身对于中文GBK编码的字符,如果你本地编码设置为UTF-8,那么按照UTF-8编码去解析出来的GBK字符,当前就是乱码了。

而只有正确设置为GBK,才能正确解析原本就是GBK编码后的字符,才能正确显示出中文。

同理,用GBK编码去解析原本用UTF-8编码后的字符,也会导致乱码。

[提示] 提示

这种乱码问题,常常会在和编码打交道的事情中遇到

比如Python中在命令行cmd中打印输出字符串,如果本身字符串是GBK编码的,那么你的cmd中的本地编码,就要设置为是936 (ANSI/OEM - Simplified Chinese GBK),这样中文字符才能正确显示。

当然,如果你本身输出的字符中,即包含UTF-8编码的字符,又包含GBK编码的字符,那么则是无论如何设置,都是无法同时正常显示的。除非你转换为Unicode编码,然后让Python输出函数自动处理,才可以正确显示。