zoukankan      html  css  js  c++  java
  • 字符集与编码

    这些东西是自己在知乎上看的,摘抄下来,以便以后查阅,主要内容有:字符集与编码、Byte Order Mark等。

    在Windows中经常需要用到多字符与宽字符的转换方法,多字符(MultiChar)也就是ANSI编码的方式,而宽字符(WideChar)也就是Unicode编码的方式。

    ANSI是默认的编码方式。对于英文文件是ASCII编码,对于简体中文文件是GB2312编码(只针对Windows简体中文版,如果是繁体中文版会采用Big5码)。

    回答的作者是梁海

    简答。一些细节暂无精力查证,如果说错了还请指出。

    一句话建议:涉及兼容性考量时,不要用记事本,用专业的文本编辑器保存为不带 BOM 的 UTF-8。


    * * *
    如果是为了跨平台兼容性,只需要知道,在 Windows 记事本的语境中:

    • 所谓的「ANSI」指的是对应当前系统 locale 的遗留(legacy)编码。[1]
    • 所谓的「Unicode」指的是带有 BOM 的小端序 UTF-16。[2]
    • 所谓的「UTF-8」指的是带 BOM 的 UTF-8。[3]

    GBK 等遗留编码最麻烦,所以除非你知道自己在干什么否则不要再用了。
    UTF-16 理论上其实很好,字节序也标明了,但 UTF-16 毕竟不常用。
    UTF-8 本来是兼容性最好的编码但 Windows 偏要加 BOM 于是经常出问题。

    所以,跨平台兼容性最好的其实就是不用记事本。
    建议用 Notepad++ 等正常的专业文本编辑器保存为不带 BOM 的 UTF-8。

    另外,如果文本中所有字符都在 ASCII 范围内,那么其实,记事本保存的所谓的「ANSI」文件,和 ASCII 或无 BOM 的 UTF-8 是一样的。


    * * *
    阮一峰那篇〈字符编码笔记:ASCII,Unicode和UTF-8〉的确很有名,但从那篇文章能看出来他其实还是没完全搞清楚 Unicode 和 UTF-8 的关系。他依旧被 Windows 的混乱措词误导。事实上,几年前我读完他那篇文章之后依旧一头雾水,最终还是自己看维基百科看明白的。
    所以,那篇文章不值得推荐。

    * * *
    关于字符集(character set)和编码(encoding),某几篇答案中似乎有些混淆。

    对于 ASCII、GB 2312、Big5、GBK、GB 18030 之类的遗留方案来说,基本上一个字符集方案只使用一种编码方案。
    比如 ASCII 这部标准本身就直接规定了字符和字符编码的方式,所以既是字符集又是编码方案;而 GB 2312 只是一个区位码形式的字符集标准,不过实际上基本都用 EUC-CN 来编码,所以提及「GB 2312」时也说的是一个字符集和编码连锁的方案;GBK 和 GB 18030 等向后兼容于 GB 2312 的方案也类似。
    于是,很多人受这些遗留方案的影响而无法理解字符集和编码的关系。

    对于 Unicode,字符集和编码是明确区分的。Unicode/UCS 标准首先是个统一的字符集标准。而 Unicode/UCS 标准同时也定义了几种可选的编码方案,在标准文档中称作「encoding form」,主要包括 UTF-8、UTF-16 和 UTF-32。
    所以,对 Unicode 方案来说,同样的基于 Unicode 字符集的文本可以用多种编码来存储、传输。
    所以,用「Unicode」来称呼一个编码方案不合适,并且误导。

    * * *
    [1] Windows 里说的「ANSI」其实是 Windows code pages,这个模式根据当前 locale 选定具体的编码,比如简中 locale 下是 GBK。把自己这些 code page 称作「ANSI」是 Windows 的臭毛病。在 ASCII 范围内它们应该是和 ASCII 一致的。
    [2] 把带有 BOM 的小端序 UTF-16 称作「Unicode」也是 Windows 的臭毛病。Windows 从 Windows 2000 开始就已经支持 surrogate pair 了,所以已经是 UTF-16 了,「UCS-2」这个说法已经不合适了。UCS-2 只能编码 BMP 范围内的字符,从 1996 年起就在 Unicode/ISO 标准中被 UTF-16 取代了(UTF-16 通过蛋疼的 surrogate pair 来编码超出 BMP 的字符)。都十多年了,求求大家别再误称了……
    [3] 把带 BOM 的 UTF-8 称作「UTF-8」又是 Windows 的臭毛病。如果忽略 BOM,那么在 ASCII 范围内与 ASCII 一致。

    * * *

    UTF-8 不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM。
    所以不含 BOM 的 UTF-8 才是标准形式,在 UTF-8 文件中放置 BOM 主要是微软的习惯(顺便提一下:把带有 BOM 的小端序 UTF-16 称作「Unicode」而又不详细说明,这也是微软的习惯)。
    BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。

    * * *

    形如——

    &#dddd;
    &#xhhhh;
    &#name;
    ——的一串字符是 HTML、XML 等 SGML 类语言的转义序列(escape sequence)。它们不是「编码」。
    以 HTML 为例,这三种转义序列都称作 character reference:
    前两种是 numeric character reference(NCR),数字取值为目标字符的 Unicode code point;以「&#」开头的后接十进制数字,以「&#x」开头的后接十六进制数字。

    后一种是 character entity reference,后接预先定义的 entity 名称,而 entity 声明了自身指代的字符。

    从 HTML 4 开始,NCR 以 Unicode 为准,与文档编码无关。

    「中国」二字分别是 Unicode 字符 U+4E2D 和 U+56FD,十六进制表示的 code point 数值「4E2D」和「56FD」就是十进制的「20013」和「22269」。所以——

    中国
    中国
    ——这两种 NCR 写法都会在显示时转换为「中国」二字。
    NCR 可以用于转义任何 Unicode 字符,而 character entity reference 很受限,参见 HTML 4 和 HTML5 中已有定义的字符列表。

     
     
  • 相关阅读:
    May 1 2017 Week 18 Monday
    April 30 2017 Week 18 Sunday
    April 29 2017 Week 17 Saturday
    April 28 2017 Week 17 Friday
    April 27 2017 Week 17 Thursday
    April 26 2017 Week 17 Wednesday
    【2017-07-04】Qt信号与槽深入理解之一:信号与槽的连接方式
    April 25 2017 Week 17 Tuesday
    April 24 2017 Week 17 Monday
    为什么丑陋的UI界面却能创造良好的用户体验?
  • 原文地址:https://www.cnblogs.com/wangaohui/p/3662833.html
Copyright © 2011-2022 走看看