alex说:一切皆bytes

一、ASCII

ASCII(American Standard Code for Information Interchange),是一种单字节的编码。计算机世界里一开始只有英文,而单字节可以表示256个不同的字符,可以表示所有的英文字符和许多的控制 符号。不过ASCII只用到了其中的一半(\x80以下),这也是MBCS得以实现的基础。

二、MBCS

然而计算机世界里很快就有了其他语言,单字节的ASCII已无法满足需求。后来每个语言就制定了一套自己的编码,由于单字节能表示的字符太少,而且同时也需要与ASCII编码保持兼容,所以这些编码纷纷使用了多字节来表示字符,如GBxxx、BIGxxx等等,他们的规则是,如果第一个字节是\x80以下,则仍然表示ASCII字符;而如果是\x80以上,则跟下一个字节一起(共两个字节)表示一个字符,然后跳过下一个字节,继续往下判断。

这里,IBM发明了一个叫Code Page的概念,将这些编码都收入囊中并分配页码,GBK是第936页,也就是CP936。所以,也可以使用CP936表示GBK。

MBCS(Multi-Byte Character Set)是这些编码的统称。目前为止大家都是用了双字节,所以有时候也叫做DBCS(Double-Byte Character Set)。必须明确的是,MBCS并不是某一种特定的编码,Windows里根据你设定的区域不同,MBCS指代不同的编码,而Linux里无法使用 MBCS作为编码。在Windows中你看不到MBCS这几个字符,因为微软为了更加洋气,使用了ANSI来吓唬人,记事本的另存为对话框里编码ANSI就是MBCS。同时,在简体中文Windows默认的区域设定里,指代GBK。

三、unicode

后来,有人开始觉得太多编码导致世界变得过于复杂了,让人脑袋疼,于是大家坐在一起拍脑袋想出来一个方法:所有语言的字符都用同一种字符集来表示,这就是Unicode。

最初的Unicode标准UCS-2使用两个字节表示一个字符,所以你常常可以听到Unicode使用两个字节表示一个字符的说法。但过了不久有人觉得256*256太少了,还是不够用,于是出现了UCS-4标准,它使用4个字节表示一个字符,不过我们用的最多的仍然是UCS-2。

UCS(Unicode Character Set)还仅仅是字符对应码位的一张表而已,比如"汉"这个字的码位是6C49。字符具体如何传输和储存则是由UTF(UCS Transformation Format)来负责。

一开始这事很简单,直接使用UCS的码位来保存,这就是UTF-16,比如,"汉"直接使用\x6C\x49保存(UTF-16-BE),或是倒过来使用\x49\x6C保存(UTF-16-LE)。但用着用着美国人觉得自己吃了大亏,以前英文字母只需要一个字节就能保存了,现在大锅饭一吃变成了两个字节,空间消耗大了一倍……于是UTF-8横空出世。

UTF-8是一种很别扭的编码,具体表现在他是变长的,并且兼容ASCII,ASCII字符使用1字节表示。然而这里省了的必定是从别的地方抠出来 的,你肯定也听说过UTF-8里中文字符使用3个字节来保存吧?4个字节保存的字符更是在泪奔……(具体UCS-2是怎么变成UTF-8的请自行搜索)

另外值得一提的是BOM(Byte Order Mark)。我们在储存文件时,文件使用的编码并没有保存,打开时则需要我们记住原先保存时使用的编码并使用这个编码打开,这样一来就产生了许多麻烦。 (你可能想说记事本打开文件时并没有让选编码?不妨先打开记事本再使用文件 -> 打开看看)而UTF则引入了BOM来表示自身编码,如果一开始读入的几个字节是其中之一,则代表接下来要读取的文字使用的编码是相应的编码:

BOM_UTF8 ‘\xef\xbb\xbf‘
BOM_UTF16_LE ‘\xff\xfe‘
BOM_UTF16_BE ‘\xfe\xff‘

并不是所有的编辑器都会写入BOM,但即使没有BOM,Unicode还是可以读取的,只是像MBCS的编码一样,需要另行指定具体的编码,否则解码将会失败。

你可能听说过UTF-8不需要BOM,这种说法是不对的,只是绝大多数编辑器在没有BOM时都是以UTF-8作为默认编码读取。即使是保存时默认使 用ANSI(MBCS)的记事本,在读取文件时也是先使用UTF-8测试编码,如果可以成功解码,则使用UTF-8解码。记事本这个别扭的做法造成了一个 BUG:如果你新建文本文件并输入"姹塧"然后使用ANSI(MBCS)保存,再打开就会变成"汉a",你不妨试试 :)

四、中文

GBK编码(Chinese Internal Code Specification)是中国大陆制订的、等同于UCS的新的中文编码扩展国家标准。gbk编码能够用来同时表示繁体字和简体字,而gb2312只能表示简体字,gbk是兼容gb2312编码的。GBK工作小组于1995年10月,同年12月完成GBK规范。该编码标准兼容GB2312,共收录汉字21003个、符号883个,并提供1894个造字码位,简、繁体字融于一库。Windows95/98简体中文版的字库表层编码就采用的是GBK,通过GBK与UCS之间一一对应的码表与底层字库联系。

一般有时把ASCII与GB2312混排称为ANSI,它与UTF-8,UNICODE,UNICODE BIG称为四种编码。

综上所述,unicode相当于一个中转站,在python3中所有编码都需要用相应的编码方式decode成unicode编码到内存中,然后才执行,python默认utf-8解码,所以非utf-8的 编码需要指定解码方式。

五、python2.x与python3.x的区别

时间: 2024-08-07 08:38:55

alex说:一切皆bytes的相关文章

python基础---文件处理

文件处理 f=open('文件','r')         打开一个文件 f.close()                关闭文件,相当于保存 1.字符编码 在文件处理过程中,首先有一个重要的概念,就是字符编码 字符编码:把人类的字符编译成计算机能认识的数字 字符编码表:就是一张字符与数字对应关系的表 ascii gbk utf-8          (硬盘中常用编码) unicode       (内存中常用编码) unicode ---->encode('utf-8') 编码---->

文件处理及函数

文件:f=open('a.txt','r',encoding='utf-8')一次读一行:print(f.readline())消除空格即\n:print(f.readline(),end='')print(f.readline(),end='')读所有:print(f.readlines())关闭文件:f.close()------------------------------------------动作完成之后可以自动完成关闭操作:with open('a.txt','r',encodin

alex python of day2

模块 sys模块:sys模块是用c语言写的,所以在lib下是不会有sys.py这个文件存在 1 import sys 2 print(sys.path) #打印环境变量 3 print(sys.argv) #打印相对路径 os模块 1 # author:"Jason lincoln" 2 import os 3 #cmd_res=os.system("dir") #只执行命令,不保存结果 4 cmd_res = os.popen("dir").r

Python3的bytes/str之别

Python 3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和bytes,正是这使得两者的区分特别清晰.你不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也不能将字符串传入参数为字节包的函数(反之亦然).这是件好事. 不管怎样,字符串和字节包之间的界线是必然的,下面的图解非常重要,务请牢记于心: 字符串可以编码成字节包,而字节包可以解码成字符

Alex 的 Hadoop 菜鸟教程: 第8课 Sqoop1 安装/导入/导出教程

靠!sqoop2的文档太少了,而且居然不支持Hbase,十分简陋,所以我愤而放弃Sqoop2转为使用Sqoop1,之前跟着我教程看到朋友不要拿砖砸我,我是也是不知情的群众 卸载sqoop2 这步可选,如果你们是照着我之前的教程你们已经装了sqoop2就得先卸载掉,没装的可以跳过这步 $ sudo su - $ service sqoop2-server stop $ yum -y remove sqoop2-server $ yum -y remove sqoop2-client 安装Sqoop

小白的Python之路 day1 Python3的bytes/str之别

原文:The bytes/str dichotomy in Python 3 Python 3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和bytes,正是这使得两者的区分特别清晰.你不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也不能将字符串传入参数为字节包的函数(反之亦然).这是件好事. 不管怎样,字符串和字节包之间的界线是必然的,下面

Python:基础数据类型:bytes

Python:基础数据类型---bytes 由于Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节.如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes. Python对bytes类型的数据用带b前缀的单引号或双引号表示: b1 = b'alex' print(b1,type(b1) b'alex' <class 'bytes'> 要注意区分'ABC'和b'ABC',前者是str,后者虽然内容显示得和前者一样,但bytes的每个字

linux一切皆文件之块设备文件(四)

一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列) 2.操作这些不同的类型就像操作文件一样,比如增删改查等 3.块设备是将信息存储在大小固定的块中,每一个块都有自己的地址,块设备支持随机访问.典型的块设备比如我们使用的硬盘 二.环境准备 组件 版本 OS Ubuntu 16.04.4 LTS 三.主设备号(major)与次设备号(minor) ● 当一块磁盘被注册到操作系统的时候,会被分配主设备号与次设备号 ● 其中

gj2 python中一切皆对象

2.1 python中一切皆是对象 动态语言和静态语言的区别,Python的面向对象更彻底 同时动态语言,代码的灵活性高 没有编译(检查)的过程,错误只有在运行起来后才会发现 函数和类也是对象,属于python的一等公民 1. 赋值给一个变量 2. 可以添加到集合对象中 3. 可以作为参数传递给函数 4. 可以当做函数的返回值 def ask(name="lewen"): print(name) class Persoon(object): def __init__(self): pr