编码发展
1. ASCII - 早期阶段
ASCII(American Standard Code for Information Interchange:美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。
早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。
2. GB2312、GBK - 各国自主编码阶段
有几万字的中文,如果处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312、GBK、GB编码,用来把中文编进去;
Shift_JIS、Euc-kr 全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
GB2312
GB2312或GB2312–80,是中华人民共和国国家标准简体中文字符集,1981年5月1日实施。GB2312编码通行于中国大陆;新加坡等地也采用此编码。GB2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;
GB2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。但对于人名、古汉语等方面出现的罕用字和繁体字,GB2312不能处理,因此后来GBK
GBK
GBK只为“技术规范指导性文件”,不属于国家标准。GBK,全名为《汉字内码扩展规范(GBK)》1.0版,由中华人民共和国全国信息技术标准化技术委员会1995年12月1日制订,GBK的K为“扩展”的汉语拼音(kuòzhǎn)第一个声母。
GBK是一种编码方式并向下兼容GB2312,GBK共收录21886个汉字和图形符号,其中汉字(包括部首和构件)21003个,图形符号883个。随后,国家质量技术监督局于2000年3月17日推出了GB18030-2000标准,以取代GBK。
3. Unicode 万国码 - 全球编码标准过程
Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
1993年,Unicode 1.1版本推出,收录中国大陆、台湾、日本及韩国通用字符集的汉字,总共有20,902个。中国大陆订定了等同于Unicode 1.1版本的“GB 13000.1-93”
4. UTF-8、UTF-16 - 基于Unicode,从存储和传输效率考虑
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部分修改,即可继续使用。
UTF-8使用一至六个字节为每个字符编码,这些多字节的最高有效比特会设置成1(尽管如此,2003年11月UTF-8被RFC 3629重新规范,只能使用原来Unicode定义的区域,U+0000到U+10FFFF,也就是说最多四个字节),:
- 128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
- 带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要两个字节编码(Unicode范围由U+0080至U+07FF)。
- 其他基本多文种平面(BMP)中的字符(这包含了大部分常用字,如大部分的汉字)使用三个字节编码(Unicode范围由U+0800至U+FFFF)。
- 其他极少使用的Unicode 辅助平面的字符使用四至六字节编码(Unicode范围由U+10000至U+1FFFFF使用四字节,Unicode范围由U+200000至U+3FFFFFF使用五字节,Unicode范围由U+4000000至U+7FFFFFFF使用六字节)。
5. Python中处理
|
|
其他编码相关内容
1. URL编码、百分号编码
百分号编码, 也称作URL编码, 是特定上下文的统一资源定位符 (URL)的编码机制,实际上也适用于统一资源标志符(URI)的编码;也用于为application/x-www-form-urlencoded
MIME准备数据, 因为它用于通过HTTP的请求操作(request)提交HTML表单数据。
编码方式:
当前是采用RFC 3986
标准,建议所有新的URI必须对未保留字符不加以百分号编码,对其他非ASCII字符, 需要转换为UTF-8字节序, 然后每个字节按照上述方式表示,比如汉字等;
- 保留字与未保留字
- 保留字:诸如
!*'();:@&=+$,/?#[]
这类有特殊含义的字符 - 未保留字:诸如
abc-z,ABC-Z,1-9,-_.~
- 保留字:诸如
- 若保留字需要特殊含义,该字符必须百分号编码;
/
为具有特殊含义的保留字符,如果在URI路径侧,则需要百分号编码; - 字符
%
号需要特殊编码为%25
- 空格被编码为
%20
,有的则被编码成+号
(有很多小的修改如新行规范化以及把空格符的编码%20
替换为+
)
转码效果
|
|
表单提交中的编码
- 如果发送的是HTTP GET请求,
application/x-www-form-urlencoded
数据包含在所请求URI的查询成分中. - 如果发送的是HTTP POST请求或通过email, 数据被放置在消息体中,媒体类型的名字被包含在消息的Content-Type头内部。
|
|
2. Base64编码
Base64是一种基于64个可打印字符来表示二进制数据的表示方法
由于2^6=64
,所以每6个比特为一个单元,对应某个可打印字符的3个字节有24个比特,对应于4个Base64单元,即原来3个字节需要由4个Base64中可打印的字符来表示,故经过Base64编码后的的长度,为原数据长度的4/3
,根据RFC 822规定,每76
个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1%
。
在Base64中的可打印字符包括字母A-Z、a-z、数字0-9
,这样共有62个字符,此外两个可打印符号在不同的系统中而不同:
- 通用MIME中:
加号+
和斜杠/
- 用于URL的改进Base64编码:
-
和_
,它不在末尾填充=号
- 用于正则表达式的改进Base64变种,它将
+
和/
改成了!
和-
- 等号
=
用来作为后缀用途
编码过程
- 转换的时候,将3字节的数据,先后放入一个24位的缓冲区中,先来的字节占高位。
- 数据不足3字节的话,于缓冲器中剩下的比特用0补足。
- 每次取出6比特,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出,直到全部输入数据转换完成。
- 若原数据长度不是3的倍数时且剩下1个输入数据,则在编码结果后加2个=;若剩下2个输入数据,则在编码结果后加1个=。
编码用途
Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,Base64它可用来作为电子邮件的传输编码、Base64图片编码等:
- 隐私增强邮件
- MIME:(多用途互联网邮件扩展)规范列出Base64编码为两个中的一个二进制到文本编码方案(比如邮件内嵌图片)
- UTF-7:它是MIME中使用的Base64编码的变体。
- 文件名:修改打印符,使用
-
而不是/
,因为文件名不能含/
,可以基于修改后的Base64再用于URL - URL紧凑:在HTTP环境中使用相当冗长的标识信息时,Base64编码会很有用。
- 在URL中使用标准Base64 需要将
+
,和=
字符编码为特殊的百分比编码的十六进制序列(+
变为%2B
,/
变为%2F
和=
变为%3D
),这使得字符串不必要地更长。 - URL增强中,标准的Base64编码将字符
+
和/
分别由-
和_
替代
- 在URL中使用标准Base64 需要将
- HTML中:
atob()
和btoa()
,javaScript方法为网页提供了Base64编码和解码功能。 - Base64用于编码脚本中的二进制文件(如图像),以避免依赖外部文件。
data URI方案
可以使用Base64编码来表示文件的内容。例如,背景图像和字体可以在CSS样式表文件中指定为data:URI
,而不是在单独的文件中提供。
3. Base58编码(64字符-6=58)
Base58是用于Bitcoin中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。相比Base64,Base58不使用数字0
,字母大写O
,字母大写I
,和字母小写l
,以及+
和/
符号。
设计Base58主要的目的是:
- 避免混淆。在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。
- 不使用"+“和”/“的原因是非字母或数字的字符串作为帐号较难被接受。
- 没有标点符号,通常不会被从中间分行。
- 大部分的软件支持双击选择整个字符串。