• 字符集与编码


    这些东西是自己在知乎上看的,摘抄下来,以便以后查阅,主要内容有:字符集与编码、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 中已有定义的字符列表。

     
     
  • 相关阅读:
    CodeForces 604D 【离散数学 置换群】
    CodeForces 604C 【思维水题】`
    CodeForces 602E【概率DP】【树状数组优化】
    CodeForces 602D 【单调队列】【简单数学】
    HDU 3535 【背包】
    CodeForces 593D【树链剖分】
    HYSBZ 1036 【树链剖分】
    POJ 2352 【树状数组】
    POJ 2182【树状数组】
    机器学习实战笔记-2-7分类机器学习形象化总结
  • 原文地址:https://www.cnblogs.com/wangaohui/p/3662833.html
Copyright © 2020-2023  润新知