您的位置:首页 > 其它

编码(1):unicode,utf-8和其他编码

2016-12-06 19:28 369 查看
1. 字符集:
ASCII字符集,最初的字符集,对应了ANSI文件编码,一个字符用一个字节表示,严格来说这个时候字符集和文本文件的编码并没有必要作为单独的概念加以区分;从此也可以看出,原来是没有中间的字符集的抽象的。字符集就是编码方式,编码解码直接对着字符集的映射表即可。二者是一个概念。
西欧字符集、日韩、港澳台、国标字符集等,仍然使用了ANSI文件编码,其中部分字符集一个字符要用两个字节;
Unicode字符集,终于在完成了字符集层面的集大成后,开始反过头来规定适合自己的文件编码(保存为ANSI会丢失大量的新增扩展字符),即Unicode Transformation Format(Unicode转换格式,其中每种方案针对不同发展阶段的使用情境设计,在其针对的情况下都能够大幅度地减少常见字的空间占用):而unicode的编码方式分为utf-8,utf-16,utf-32
历史:[character set] 字符集历史
计算机的发明。由于一个字节(Byte)有8位(bit),类似10101010,因此一个基本的存储单位能够表示2的8次方(即256)种字符,而基本的计算机字符(所谓的半角字符,说白了是发明计算机的美国常用的字符)用128个就表示完了,所以这时候不存在任何问题,一个字节(计算机存储单位)对应一个字符(人类自然语言文字中的单位),这套字符集被称为ASCII,包括了半角英文大小写、半角数字、半角表单符号等。闲得无聊的美国人还用多出来的一位作校验码,用于避免电路不稳定信号传输错误(其实是看着浪费不顺眼)。
(之所以一个字节不是7位,是考虑到2的整数幂,要么4位、要么16位,8位刚好够用,后文会看出幸好如此,否则很难想象有预留的先见之明,毕竟研究各国文化恐怕比发明计算机还麻烦。)
后来欧洲语言的扩充。计算机的世界化过程中,欧洲紧随其后。他们马上发现各种注音的拉丁语系字母无法表示,因此把后128位直接用上了,128+128,皆大欢喜。
(一方面这可以理解为目光短浅,另一方面也确实没有必要浪费更多空间。)
世界另一边象形文字的扩充。以中文为例,虽然比欧洲稍晚,但实际上应当与欧洲理解为第二传播梯队同期的各自闭门造车。由于中文太多,索性用多个计算机字节(两个)表示一个中文字符。为了避免与美国原始体系冲突,我们规定当一个字节在128以内时,还是原义;超出128的,需要与后面一个字节组合解读成一个字符。这样128瞬间变成了128*256,完全够用了。这套字符集命名以GB(国标)开头,有过几次扩充(GB2312、GBK、GB18030),相互不完全兼容,与欧洲扩展字符集自然也不兼容。注意中国人用计算机也是要处理拉丁文、日韩等文字的,所以其中并不只有中文,只是各国实现的标准不同。同期产生的还有Big5(港澳台地区繁体中文标准)、JIS(日本)等。
(表面上看起来各国各自为营很不合理,实际上一开始就要考虑所有问题会导致各自极其不合理,而事实上各自为营的发展速度和地位上升才是后一步的现实前提。)
世界统一标准。随着互联网的发展,计算机工业不再仅限于处理不同的文字,还必须用同一套方式处理。Universal Character Set,简称UCS,别名Unicode(实际是两个并行起草的字符集,快弄好了才发现彼此干脆合并了协议),应运而生。Unicode包罗万象,并预留好了无限扩展的方案。随着计算机硬件发展,这种通用方案虽然略浪费空间,却极大地节省了人的工作成本。

2. 还有一点,就是之所以unicode分成字符集和编码方式,但是gb2312,ascii等貌似就没有字符集。因为那个时候计算机没有普及,需求没有这么大,就不用单独抽象出一个字符集的概念。此时编码方式和字符集是一个东西。无论编码解码,直接对照字符集的映射表就可以完成。另外,字符集其实和文件对物理磁盘的抽象一样。属于后来为了方便,对字符集合和编码分开。这样有了中间的一层抽象,即使字符集有变化,编码方式也不需要改变。如果直接使用
“字符串↔️字符↔️二进制表示(编码)” ,会增加不同类型编码之间转换的复杂性。所以引入了一个抽象层,“字符串↔️字符↔️与存储无关的表示↔️二进制表示(编码)” ,这样,可以用一种与存储无关的形式表示字符,不同的编码之间转换时可以先转换到这个抽象层,然后再转换为其他编码形式。在这里,unicode 就是 “与存储无关的表示”,utf—8 就是 “二进制表示”。

3. unicode是字符集,没有所谓的几个字节。而utf是unicode绑定的编码方式。utf-8是1,2,3,4个字节,utf-16是2,4个字节,utf-32是4个字节。各有各的好。因为8位是对大量使用英文很有优势,这个可以节省存储空间应该都明白。但是,如果对于那些无法用一个字节表示的字符使用8位,就会浪费。因为当使用变长的字节来编码的时候,是需要牺牲掉一部分来让编码器知道是应该把两个字节,还是单个字节亦或者更多字节放到一起读的。具体可以看下面的例子。可见,Unicode字符集层面的概念,处理的是每个汉字对应的计算机编号。做个简单的比喻,
unicode相当于中文, UTF-8, UTF-16等相当于 行书, 楷书, 草书等各种书写方式.
4. 任何文本都是有编码的。但是,如果只有英文,即使编码不对,一般不会报错。因为大部分编码都是兼容acsii的。
5. 之所以Content-Type: text/html; charset=UTF-8,UTF-8本身是文件编码信息,却写在charset(字符集)的位置,其实是暗示了其从属的Unicode字符集系统,同时又顺便指出了文件编码信息(因为二者是高度绑定的关系),

6. 计算机内只能保存101010等二进制数据,那么页面上显示的字符是如何显示出来的呢?

一:字符集(Charset)

charset = char + set,char 是字符,set是集合,charset就是字符的集合。

字符集就是是这个编码方式涵盖了哪些字符,每个字符都有一个数字序号。

二:编码方式(Encoding)

编码方式就是一个字符要怎样编码成二进制字节序,或者反过来怎么解析。

也即给你一个数字序号,要编码成几个字节,字节顺序如何,或者其他特殊规则。

三:字形字体(Font)

根据数字序号调用字体存储的字形,就可以在页面上显示出来了。

所以一个字符要显示出来,要显示成什么样子要看字体文件。

7. 编码从总体上分为文件层和包装层:

保证层是对文件层在传输过程中的包装。有点类似网络分层的味道。具体看下面的附录:
8. 再次确认,所有的short,int等都是用二的补码表示的。也就是如果int是4个字节,就是-2^31~2^31-1. 如果是一位,就是-128~127

9. 以后请不要在问是用unicode还是utf-8了,二者不是一个层次的东西。也不要问unicode有几个字节了,它压根没有上限。如果有需要,一百个字节也可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj