最近接了一个单是需要把非 UTF-8 (No BOM)编码的文件转换成 UTF-8 (No BOM),若此文件是 UTF-8 但带有 BOM ,需要转换成不带 BOM 的。于是开启了一天的阅读。首先花了一上午阅读“文件编码格式(转) - lionking - 博客园 ”这篇文章,阅读完后终于明白了“UTF-8 不是字符集”这句话。之后怕混淆再阅读了“字符集和字符编码(Charset&Encoding) - 博客 - 伯乐在线  ”确认。

 
这篇文章纯粹是用通俗的语言解释我以前混淆的几个概念,对于具体的规范不做解释,希望大家有像我一样疑惑的读完后不再疑惑,可以在需要时查阅正式的规范是解决需要的问题。
 
我们都清楚打开记事本看见一个字母 a ,它在磁盘上的二进制值是 0x61 。正是字符集让 0x61 显示成小写字母 a 。因此字符集和字符集中显示的字符是一一对应的。
我之前一直被“编码”这个词搞混了。因为在我们的日常交流或者看博客看书等都可以看见下面一些类似的话:
■“xxx 以 ASCII 编码显示为 yyy”。
■“该文件在 Windows 上以 ANSI 编码,在 Linux 下无法正常显示,需要在 Windows 上以 UTF-8 编码保存这样就可以在 Linux 下打开就不会乱码了”
■“UTF-8 不是字符集只是一种编码标准”。
这几句话给我造成了以下疑惑。
■“ASCII 和 ANSI 不是字符集么,怎么这里用来编码了”。
■“UTF-8 不是字符集,怎么可以用来编码呢?查查资料说采用 Unicode 字符集,Unicode 说是同一码,到底是个啥玩意?”。
 
首先,字符集(character encoding 或 character set)定义了二进制与字符的对应关系。通过字符集可以把字符转换成相应的二进制用于存储和传输,当需要阅读文字时,可以通过字符集把二进制转换成相应的字符。作为程序员我们都知道 ASCII 字符集(ASCII 码)是7位的,一共只能表示128个字符,具体内容,网上搜索都可以找到。
 
在继续往下写之前先在这里说明一下”什么是 ANSI 字符集,它和 ASCII 字符集有什么关联?“。
我最初见到提及”ANSI 字符集“的地方是在《Windows 程序设计》这本书中。书中前面就介绍 ANSI 字符集和 Unicode 字符集,可惜我当初看了几遍也没有看出个所以然,还有就是用 VC 写程序时,在”项目设置“有一项设置”字符集“,是个下拉框可以选择”ANSI 字符集“和”Unicode 字符集“。当时我也不知道到底是什么意思,反正只知道书中建议程序员多用 Unicode 程序集。所以我对于 ANSI 字符集和 Unicode 字符集的印象一直都是多用 Unicode 字符集。为什么说印象呢?因为我不知道具体是啥。
其实没有具体的某个字符集叫 ANSI 字符集,它只是在 Windows 上面的一个统称。ANSI 字符集应该来源于 ANSI 代码页(代码页其实就是字符集,只是早期的叫法而已)。因为 Windows 代码页最初是根据 ANSI 草案实现的,所以 Windows 代码页又叫做 ANSI 代码页。之后字符集这个词出现了,应该就把这些代码页叫做 ANSI 字符集了吧。在维基百科上面有关于代码页的介绍。ASCII 字符集是7位的,一共只能表示128个字符,表示其他语言就成了问题,后来对 ASCII 字符集进行了扩展,用两个字节表示其他语言,这样就绰绰有余了。比如简体中文 GB2312,繁体中文 big5,日语 SHIFT_JIS 。举个比较通俗(没有那么准确)的例子,在中国大陆的 Windows 电脑中 ANSI 字符集是指 GB2312 ,在中国台湾 Windows 电脑中 ANSI 字符集是指 big5,在日本 Windows 电脑中 ANSI 字符集是指 SHIFT_JIS 。就是这么个概念。这些字符集中每个字符都是以2字节编码,因此这种字符集又叫 DBCS 。
 
接着。以上我产生了两个疑惑。其实第一个疑惑完全是被表述误解。比如根据 ASCII 字符集把 0x61 显示为 a ,或者把 a 存储为 0x61 ,这句话也有人习惯表述为把 0x61 用 ASCII 编码为 a ,用 ASCII 把 a 解码为 0x61 。其实都是一个意思。因此关于编码这个词应该根据上下文语意来进行理解。
第二个疑惑是把 Unicode 字符集与 ASCII 字符集、ANSI 字符集和 GB2312 字符集搞混淆了。前面我们提到的 ANSI 字符集以2字节编码,比如在简体中文中 0x1234 是指某个字,到了繁体中文就成了另外一个字,到了日语又是一个日语字符。Unicode 是一个统称,当提到 Unicode 字符集其实是指 Universal Character Set, UCS 。我们可以说 Unicode 字符集,当然也可以说 UCS 字符集。UCS 字符集包括了其他所有语言的文字,比如拉丁语,简体中文,繁体中文,日语,韩语等。也就是说不同的语言中的不同字符在 UCS 中都一个唯一的位置,而不是像 ANSI 字符集那样,2字节在不同的地方表示不同的语言文字。这样 UCS 就实现了所有语言的大一统,当然 UCS 的字节数不止2字节,UCS 分为 UCS-2 和 UCS-4 ,分别表示占用2字节时表示的字符和占用4字节时占用的字符,在 UCS-2 前面加2个值为0的字节就变成了 UCS-4 。
我们明白了 Unicode 字符集,但是 Unicode 字符集在日常使用时并非直接使用字符对应的二进制,而是会对这个二进制再次编码后使用,或用于网络传输或用于磁盘保存。这种编码方法就叫做 UTF , Unicode Transformation Format 。
常见的 UTF 编码有 UTF-32,UTF-16,UTF-8 。UTF-8 由于特殊的算法是不需要额外声明字节序,但 UTF-32 或者 UTF-16 则不行,如果我们收到 UTF-16 字节流“594E”,不知道它的值是 0x594E 还是 0x4E59,这是”奎“还是 ”乙“?Unicode 规范中推荐的标记字节顺序的方法是 BOM ,Byte Order Mark。在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE“的字符,它的值是 0xFEFF,而 0xFEFF 在 UCS 中是不存在的字符。这样如果接收者收到 FEFF ,就表明这个字节流是 Big-Endian 的;如果收到 FFFE ,就表明这个字节流是 Little-Endian 的。UTF-8 不需要 BOM来表明字节顺序,但可以用 BOM 来表明编码方式。字符”ZERO WIDTH NO-BREAK SPACE“的UTF-8编码是 EF BB BF 。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
 
总结:
1)
ASCII 字符集是7位标识拉丁语的字符集。
Unicode 字符集就是指 UCS 字符集,它是统一定义了所有语言中的字符(目前绝大部分语言都有包括进去)。
ANSI 字符集是在 Windows 上面的一个统称,这些字符集是2字节编码,由 ASCII 字符集拓展而来。简体中文 GB2312 ,繁体中文 big5 都可以划分到这个范畴。
2)
代码页就是字符集。只是早期的叫法而已。
3)
UTF 是 Unicode 字符集的传输格式,这里传输是翻译成中文的叫法,可以在网络上传输也可以在磁盘上保存文件。UTF 本身不是字符集,是基于 Unicode 字符集。
 
引用:
1) 百度百科。ANSI 编码。http://baike.baidu.com/view/1273097.htm
2) 维基百科。Unicode。https://zh.wikipedia.org/wiki/Unicode
(注:维基百科中文已被墙!)

ASCII UNICODE UTF "口水文"的更多相关文章

  1. Unicode(UTF&UCS)深度历险

    Unicode(UTF&UCS)深度历险 计算机网络诞生后,大家慢慢地发现一个问题:一个字节放不下一个字符了!因为需要交流,本地化的文字需要能够被支持. 最初的字符集使用7bit来存储字符,因 ...

  2. 浅显总结ASCII Unicode UTF-8的区别

    如果觉得此地排版不好,欢迎访问我的博客 浅显总结ASCII Unicode UTF-8的区别 制作表单时,为了追求更好的用户交互体验,常常会有提示性的内容,比如提醒用户字符的限制.由于英文,中文字符的 ...

  3. 字符编码 ASCII,Unicode和UTF-8的关系

    转自:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143166410626 ...

  4. 字符编码 ASCII unicode UTF-8

    字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(b ...

  5. 字符集、字符编码、国际化、本地化简要总结(UNICODE/UTF/ASCII/GB2312/GBK/GB18030)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 环境说明   普通的linux 和 普通的windows.    ...

  6. Unicode, UTF, ASCII, ANSI format differences

    Going down your list: "Unicode" isn't an encoding, although unfortunately, a lot of docume ...

  7. 【转】【编码】ANSI,ASCII,Unicode,UTF8之一

          不同的国家和地区制定了不同的标准,由此产生了 GB2312.GBK.GB18030.Big5.Shift_JIS 等各自的编码标准.这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称 ...

  8. 码表 ASCII Unicode GBK UTF-8

    2017-1-3 [ASCII]一个字节(7位,128个字符,2个16进制) 不包含中文 ASCII(American Standard Code for Information Interchang ...

  9. ASCII, Unicode, UTF-8, 8进制, 16进制等各种编码学习理解笔记

    字符编码的发展历史 Unicode和UTF-8有何区别? 在这个问题下的于洋的最高票回答中,比较完整地介绍了字符编码的发展历史,为了便于记忆,再次简要概括一番. 一个字节:最初一个字节的标准是混乱的, ...

随机推荐

  1. (五)解决jQuery和其它库的冲突

    在jQuery库中,几乎所有的插件都被限制在它的命名空间里.全局的对象都很好地存储在jQuery命名空间里,因此当把jQuery和其它javascript类库一起使用时,不会引起冲突.(注意:默认情况 ...

  2. android:scrollbar的一些属性

    1. activity_maim.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android ...

  3. 优秀JS学习站点

    第一个:电子书类集合站点:http://www.javascriptcn.com/thread-2.html 第二类:移动端博客学习: https://segmentfault.com/a/11900 ...

  4. SQLServer -- SQL Server Database Error: 内部 SQL Server 错误

    报表在SQLserver2008运行统计正常,但是在SQLserver2000运行报错,SQL直接执行报:内部 SQL Server 错误. 不断的排查,最终得到的结论是:SQLserver2000似 ...

  5. 目标检测之基础hessian matrix ---海森矩阵

    就是海赛(海色)矩阵,在网上搜就有. 在数学中,海色矩阵是一个自变量为向量的实值函数的二阶偏导数组成的方块矩阵, Hessian矩阵是多维变量函数的二阶偏导数矩阵,H(i,j)=d^2(f)/(d(x ...

  6. 【转】cmd chcp命令切换字符格式

    cmd chcp命令切换字符格式   命令介绍:   chcp 65001   #换成utf-8代码页   chcp 936       #换成默认的gbk   chcp 437       #美国英 ...

  7. Android中RelativeLayout各个属性及其含义

    android:layout_above="@id/xxx"  --将控件置于给定ID控件之上android:layout_below="@id/xxx"  - ...

  8. 五个知识体系之-SQL学习-第三天

    1. sql约束作用 主键约束作用:保证插入数据的有效性.比如性别列,只能是“男”“女”,输入“abc”就是无效的,所以你可以添加约束alter table 表名add constraint chk_ ...

  9. EasyPlayer Android安卓RTSP服务器低延时再优化策略

    EasyPlayer低延迟再优化策略 EasyPlayer是一款专门针对RTSP协议进行过优化的播放器.其中两个我们引以为傲的的优点就是起播快和低延迟.最近我们遇到一些需求,其对延迟要求非常苛刻,于是 ...

  10. 双缓冲类里的OnPaint与OnSize,以及构造函数的关系

    代码摘自wx\lib\agw\knobctrl.py一点体会是,OnSize作为class的函数,被放在构造函数里执行,会先于OnPaint执行.测试结果是,初始启动后,会执行8次OnSize(为什么 ...