几种常见 字符编码详解.docx

上传人:b****8 文档编号:8936131 上传时间:2023-02-02 格式:DOCX 页数:11 大小:71.73KB
下载 相关 举报
几种常见 字符编码详解.docx_第1页
第1页 / 共11页
几种常见 字符编码详解.docx_第2页
第2页 / 共11页
几种常见 字符编码详解.docx_第3页
第3页 / 共11页
几种常见 字符编码详解.docx_第4页
第4页 / 共11页
几种常见 字符编码详解.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

几种常见 字符编码详解.docx

《几种常见 字符编码详解.docx》由会员分享,可在线阅读,更多相关《几种常见 字符编码详解.docx(11页珍藏版)》请在冰豆网上搜索。

几种常见 字符编码详解.docx

几种常见字符编码详解

编程综合

blog.minidx./2021/10/22/1570.html

blog.minidx./2021/11/06/1607.html

blog.minidx./2021/12/06/1689.html

blog.minidx./2021/12/09/1700.html

 

 

摘录1:

 

 

GBK范围:

1stbyte|2ndbyte

0×81~0xfe|0×40~0×7eand0×80~0xfe

BIG5范围:

1stbyte|2ndbyte

0×81~0xfe|0×40~0×7eand0xa1~0xfe

下面是来自libiconv的关于GBK〔cp936〕和BIG5〔cp950〕的两段代码,相信还是相当有用的。

 

摘录2:

 

 

一预备知识1,字符:

字符是抽象的最小文本单位。

它没有固定的形状〔可能是一个字形〕,而且没有值。

“A〞是一个字符,“€〞〔德国、法国和许多其他欧洲国家通用货币的标志〕也是一个字符。

“中〞“国〞这是两个汉字字符。

字符仅仅代表一个符号,没有任何实际值的意义。

2,字符集:

字符集是字符的集合。

例如,汉字字符是中国人最先创造的字符,在中文、日文、韩文和越南文的书写中使用。

这也说明了字符和字符集之间的关系,字符组成字符集〔iso8859-1,GB2312/GBK,unicode〕。

3,代码点:

字符集中的每个字符都被分配到一个“代码点〞。

每个代码点都有一个特定的唯一数值,称为标值。

该标量值通常用十六进制表示。

4,代码单元:

 在每种编码形式中,代码点被映射到一个或多个代码单元。

“代码单元〞是各个编码方式中的单个单元。

代码单元的大小等效于特定编码方式的位数:

UTF-8:

UTF-8中的代码单元由8位组成;在UTF-8中,因为代码单元较小的缘故,每个代码点常常被映射到多个代码单元。

代码点将被映射到一个、两个、三个或四个代码单元;

UTF-16:

UTF-16中的代码单元由16位组成;UTF-16的代码单元大小是8位代码单元的两倍。

所以,标量值小于U+10000的代码点被编码到单个代码单元中;

UTF-32:

UTF-32 中的代码单元由32位组成; UTF-32中使用的32位代码单元足够大,每个代码点都可编码为单个代码单元;

GB18030:

GB18030 中的代码单元由8位组成;在GB18030中,因为代码单元较小的缘故,每个代码点常常被映射到多个代码单元。

代码点将被映射到一个、两个或四个代码单元。

5,举例:

“中国香蕉是个大笨蛋〞这是我定义的aka字符集;各字符对应代码点为:

北00000001

京00000010

香10000001

蕉10000010

是10000100

个10001000

大10010000

笨10100000

蛋11000000

中00000100

国00001000

下面是我定义的zixia编码方案〔8位〕,可以看到它的编码中表示了aka字符集的所有字符对应的代码单元;

北10000001

京10000010

香00000001

蕉00000010

是00000100

个00001000

大00010000

笨00100000

蛋01000000

中10000100

国10001000

所谓文本文件就是我们按一定编码方式将二进制数据表示为对应的文本如00000001000000100000010000001000000100000010000001000000这样的文件。

我用一个支持zixia编码和aka字符集的记事本翻开,它就按照编码方案显示为 “香蕉是个大笨蛋〞

如果我把这些字符按照GBK另存一个文件,那么那么肯定不是这个,而是

110011*********1101111011011011011001010110001111011100011110110101101001111001110110001101111111011010110110000110100001010

二,字符集1,常用字符集分类ASCII及其扩展字符集

作用:

表语英语及西欧语言。

位数:

ASCII是用7位表示的,能表示128个字符;其扩展使用8位表示,表示256个字符。

范围:

ASCII从00到7F,扩展从00到FF。

ISO-8859-1字符集

作用:

扩展ASCII,表示西欧、希腊语等。

位数:

8位,

范围:

从00到FF,兼容ASCII字符集。

GB2312字符集

作用:

国家简体中文字符集,兼容ASCII。

位数:

使用2个字节表示,能表示7445个符号,包括6763个汉字,几乎覆盖所有高频率汉字。

范围:

高字节从A1到F7,低字节从A1到FE。

将高字节和低字节分别加上0XA0即可得到编码。

BIG5字符集

作用:

统一繁体字编码。

位数:

使用2个字节表示,表示13053个汉字。

范围:

高字节从A1到F9,低字节从40到7E,A1到FE。

GBK字符集

作用:

它是GB2312的扩展,参加对繁体字的支持,兼容GB2312。

位数:

使用2个字节表示,可表示21886个字符。

范围:

高字节从81到FE,低字节从40到FE。

GB18030字符集

作用:

它解决了中文、日文、朝鲜语等的编码,兼容GBK。

位数:

它采用变字节表示(1ASCII,2,4字节)。

可表示27484个文字。

范围:

1字节从00到7F;2字节高字节从81到FE,低字节从40到7E和80到FE;4字节第一三字节从81到FE,第二四字节从30到39。

UCS字符集

作用:

国际标准ISO10646定义了通用字符集(UniversalCharacterSet)。

它是与UNICODE同类的组织,UCS-2和UNICODE兼容。

位数:

它有UCS-2和UCS-4两种格式,分别是2字节和4字节。

范围:

目前,UCS-4只是在UCS-2前面加了0×0000。

UNICODE字符集

作用:

为世界650种语言进展统一编码,兼容ISO-8859-1。

位数:

UNICODE字符集有多个编码方式,分别是UTF-8,UTF-16和UTF-32。

2 ,按所表示的文字分类

语言                                 字符集                                     正式名称

英语、西欧语                     ASCII,ISO-8859-1                MBCS多字节

简体中文                             GB2312                                   MBCS多字节

繁体中文                             BIG5                                         MBCS多字节

简繁中文                             GBK                                         MBCS多字节

中文、日文及朝鲜语         GB18030                                 MBCS多字节

各国语言                             UNICODE,UCS                    DBCS宽字节

三,编码UTF-8:

采用变长字节(1ASCII,2希腊字母,3汉字,4平面符号)表示,网络传输,即使错了一个字节,不影响其他字节,而双字节只要一个错了,其他也错了,具体如下:

如果只有一个字节那么其最高二进制位为0;如果是多字节,其第一个字节从最高位开场,连续的二进制位值为1的个数决定了其编码的字节数,其余各字节均以10开头。

UTF-8最多可用到6个字节。

UTF-16:

采用2字节,Unicode中不同局部的字符都同样基于现有的标准。

这是为了便于转换。

从0×0000到0×007F是ASCII字符,从0×0080到0×00FF是ISO-8859-1对ASCII的扩展。

希腊字母表使用从0×0370到0×03FF的代码,斯拉夫语使用从0×0400到0×04FF的代码,美国使用从0×0530到0×058F的代码,希伯来语使用从0×0590到0×05FF的代码。

中国、日本和韩国的象形文字〔总称为CJK〕占用了从0×3000到0×9FFF的代码;由于0×00在c语言及操作系统文件名等中有特殊意义,故很多情况下需要UTF-8编码保存文本,去掉这个0×00。

举例如下:

UTF-16:

0×0080 =0000000010000000

UTF-8:

  0xC280=1100001010000000

UTF-32:

采用4字节。

优缺点

UTF-8、UTF-16和UTF-32都可以表示有效编码空间(U+000000-U+10FFFF)内的所有Unicode字符。

使用UTF-8编码时ASCII字符只占1个字节,存储效率比拟高,适用于拉丁字符较多的场合以节省空间。

对于大多数非拉丁字符〔如中文和日文〕来说,UTF-16所需存储空间最小,每个字符只占2个字节。

WindowsNT内核是Unicode〔UTF-16〕,采用UTF-16编码在调用系统API时无需转换,处理速度也比拟快。

采用UTF-16和UTF-32会有BigEndian和LittleEndian之分,而UTF-8那么没有字节顺序问题,所以UTF-8适合传输和通信。

UTF-32采用4字节编码,一方面处理速度比拟快,但另一方面也浪费了大量空间,影响传输速度,因而很少使用。

四,如何判断字符集1,字节序

首先说一下字节序对编码的影响,字节序分为BigEndian字节序和LittleEndian字节序。

不同的处理器可能不一样。

所以,传输时需要告诉处理器当时的编码字节序。

对于前者而言,高位字节存在低地址,低字节存于高地址;后者相反。

例如,0X03AB,

BigEndian字节序

0000:

03

0001:

AB

LittleEndian字节序是

0000:

AB

0001:

03

2,编码识别UNICODE,根据前几个字节可以判断UNICODE字符集的各种编码,叫做ByteOrderMask方法BOM:

UTF-8:

EFBBBF(符合UTF-8格式,请看上面。

但没有含义在UCS即UNICODE中)

UTF-16BigEndian:

FEFF(没有含义在UCS-2中)

UTF-16LittleEndian:

FFFE(没有含义在UCS-2中)

UTF-32BigEndian:

0000FEFF(没有含义在UCS-4中)

UTF-32LittleEndian:

FFFE0000(没有含义在UCS-4中)

GB2312:

高字节和低字节的第1位都是1。

BIG5,GBK&GB18030:

高字节的第1位为1。

操作系统有默认的编码,常为GBK,可以下载别的并升级。

通过判断高字节的第1位从而知道是ASCII或者汉字编码。

 

python与字符编码:

ASCII是一种字符集,包括大小写的英文字母、数字、控制字符等,它用一个字节表示,范围是0-127

Unicode分为UTF-8和UTF-16。

UTF-8变长度的,最多6个字节,小于127的字符用一个字节表示,与ASCII字符集的结果一样,ASCII编码下的英语文本不需要修改就可以当作UTF-8编码进展处理。

Python从2.2开场支持Unicode,函数decode(char_set)可以实现其它编码到Unicode的转换,函数encode(char_set)实现Unicode到其它编码方式的转换。

比方("你好").decode("GB2312")将得到u'\u4f60\u597d',即"你"和“好"的Unicode码分别是0x4f60和0x597d

再用(u'\u4f60\u597d').encode("UTF-8")将得到'\xe4\xbd\xa0\xe5\xa5\xbd',它是 “你好〞的UTF-8编码结果。

python中使用unicode的关键:

unicode是一个类,函数unicode(str,"utf8")从utf8编码〔当然也可以是别的编码〕的字符串str生成unicode类的对象,而函数unc.encode("utf8")将unicode类的对象unc转换为〔编码为〕utf8编码〔当然也可以是别的编码〕的字符串。

于是,编写unicode相关程序,需要做的事情是

   *获取数据〔字符串〕时,用unicode(str,"utf8")生成unicode对象

   *在程序中仅使用unicode对象,对程序中出现的字符串常量都以u"字符串"的形式书写

   *输出时,可将unicode对象转换为任意编码输出,使用str.encode("some_encoding")

>>>unicode("你好","utf8")

u'\u4f60\u597d'>>>x=_

>>>type(x)

>>>type("你好")

>>>x.encode("utf8")

'\xe4\xbd\xa0\xe5\xa5\xbd'

>>>x.encode("gbk")

'\xc4\xe3\xba\xc3'

>>>x.encode("gb2312")

'\xc4\xe3\xba\xc3'

>>>printx

你好

>>>printx.encode("utf8")

你好

>>>printx.encode("gbk")

?

?

?

 

python里面根本上要考虑三种编码格式

1源文件编码

在文件头部使用coding声明。

告诉python解释器该代码文件所使用的字符集。

#/usr/bin/python

#coding:

utf8

2内部编码

代码文件中的字符串,经过decode以后,被转换为统一的unicode格式的内部数据,类似于u'*'。

unicode数据可以使用encode函数,再自由转换为其他格式的数据,相当于一个统一的平台。

直接输入unicode数据

>>>u'你好'

u'\u4f60\u597d'

将unicode数据转换为gb2312格式

>>>u'你好'.encode('gb2312')

'\xc4\xe3\xba\xc3'

将输入的gb2312格式的数据解码为unicode

>>>'你好'.decode('gb2312')

u'\u4f60\u597d'

输入数据的格式取决于所用shell终端的编码设置,本例中为zh_[rootchenzhengpython]#echo$LANG

zh_

解码同时转换为utf8

>>>'你好'.decode('gb2312').encode('utf8')

'\xe4\xbd\xa0\xe5\xa5\xbd'

3外部输入的编码

其实这个和在python交互shell中输入的字符串,所遇到的情况根本一样。

但程序中常常用到从网络,文件读取的数据,故此单独列出,需要特别注意其编码格式是否于系统要求相符。

下面是baidu中文本周金曲榜的,返回一个xml文件,编码格式为gb2312

box.zhangmen.baidu./x?

op=4&listid=1

由于xml.etree.EelementTree.parse()不识别gb2312编码,在解析的时候,需要将其转换utf8格式才可以,可以使用下面的函数

defread_page(url):

"""读取gb2312编码的xml文件,转换为utf8格式"""

importurllib

udata=urllib.urlopen(url).read().decode('gb2312')

u8data=udata.encode('utf8')

returnu8data.replace('gb2312','utf-8')#简单替换xml文件第一行的encoding属性值

另外,可以使用一个小函数来判断数据的编码格式:

defencoding(s):

cl=['utf8','gb2312']

foraincl:

try:

s.decode(a)

returna

exceptUnicodeEncodeError:

pass

return'unknown' 

 

被广泛的“在中使用中文〞

我也一下:

 

 

1.在中使用中文

在中有两种默认的字符串:

str和unicode。

在中一定要注意区分“Unicode字符串〞和“unicode对象〞的区别。

后面所有的“unicode字符串〞指的都是里的“unicode对象〞。

事实上在中并没有“Unicode字符串〞这样的东西,只有“unicode〞对象。

一个传统意义上的unicode字符串完全可以用str对象表示。

只是这时候它仅仅是一个字节流,除非解码为unicode对象,没有任何实际的意义。

我们用“哈哈〞在多个平台上测试,其中“哈〞对应的不同编码是:

1. UNICODE (UTF8-16),C854;

2. UTF-8,E59388;

3.GBK,B9FE。

1.1Windows控制台

下面是在windows控制台的运行结果:

可以看出在控制台,中文字符的编码是GBK而不是UTF-16。

将字符串s〔GBK编码〕使用decode进展解码后,可以得到同等的unicode对象。

注意:

可以在控制台打印ss并不代表它可以直接被序列化,比方:

向文件直接输出ss会抛出同样的异常。

在处理unicode中文字符串的时候,必须首先对它调用encode函数,转换成其它编码输出。

这一点对各个环境都一样。

总结:

在中,“str〞对象就是一个字节数组,至于里面的内容是不是一个合法的字符串,以及这个字符串采用什么编码〔gbk, utf-8,unicode〕都不重要。

这些内容需要用户自己记录和判断。

这些的限制也同样适用于“unicode〞对象。

要记住“unicode〞对象中的内容可绝对不一定就是合法的unicode字符串,我们很快就会看到这种情况。

总结:

在windows的控制台上,支持gbk编码的str对象和unicode编码的unicode对象。

1.2WindowsIDLE〔在Shell上运行〕

在windows下的IDLE中,运行效果和windows控制台不完全一致:

可以看出,对于不使用“u〞作标识的字符串,IDLE把其中的中文字符进展GBK编码。

但是对于使用“u〞的unicode字符串,IDLE居然一样是用了GBK编码,不同的是,这时候每一个字符都是unicode〔对象〕字符!

此时len(ss)=4。

这样产生了一个神奇的问题,现在的ss无法在IDLE中正常显示。

而且我也没有方法把ss转换成正常的编码!

比方采用下面的方法:

这有可能是因为IDLE本地化做得不够好,对中文的支持有问题。

建议在IDLE的SHELL中,不要使用u“中文〞这种方式,因为这样得到的并不是你想要的东西。

这同时说明IDLE的Shell支持两种格式的中文字符串:

GBK编码的“str〞对象,和UNICODE编码的unicode对象。

1.3在IDLE上运行代码

在IDLE的SHELL上运行文件,得到的又是不同的结果。

文件的内容是:

直接运行的结果是:

毫无瑕疵,相当令人满意。

我没有试过其它编码的文件是否能正常运行,但想来应该是不错的。

同样的代码在windows的控制台试演过,也没有任何问题。

1.4WindowsEclipse

在Eclipse中处理中文更加困难,因为在Eclipse中,编写代码和运行代码属于不同的窗口,而且他们可以有不同的默认编码。

对于如下代码:

代码:

#!

/usr/bin/#-*-coding:

 utf-8-*-

 

s= "哈哈"

ss= u'哈哈'

 print repr(s)print repr(ss)

 print s.decode('utf-8').encode('gbk')print ss.encode('gbk')

 print s.decode('utf-8')print ss

前四个print运行正常,最后两个print都会抛出异常:

代码:

'\xe5\x93\x88\xe5\x93\x88'u'\u54c8\u54c8'

哈哈

哈哈

Traceback (mostrecentcalllast):

 File "E:

\Workspace\Eclipse\TestPython\Test\test_encoding_2.py",line 13, in 

   print s.decode('utf-8')UnicodeEncodeError:

 'ascii' codeccan'tencodecharactersinposition0-1:

ordinalnotinrange(128)

也就是说,GBK编码的str对象可以正常打印,但是不能打印UNICODE编码的unicode对象。

在源文件上点击“Runas〞“Run〞,然后在弹出对话框中选择“mon〞:

可以看出Eclipse控制台的缺省编码方式是GBK;所以不支持UNICODE也在情理之中。

如果把文件中的coding修改成GBK,那么可以直接打印GBK编码的str对象,比方s。

如果把源文件的编码设置成“UTF-8〞,把控制台的编码也设置成“UTF-8〞,按道理说打印的时候应该没有问题。

但是实验说明,在打印UTF-8编码的str对象时,中文的最后一个字符会显示成乱码,无法正常阅读。

不过我已经很满足了,至少人家没有抛异常不是:

BTW:

使用的Eclipse版本是3.2.1。

1.5从文件读取中文

在window下面用记事本编辑文件的时候,如果保存为UNICODE或UTF-8,分别会在文件的开头加上两个字节“\xFF\xFE〞和三个字节“\xEF\xBB\xBF〞。

在读取的时候就可能会遇到问题,但是不同的环境对这几个多于字符的处理也不一样。

以windows下的控制台为例,用记事本保存三个不同版本的“哈哈〞。

翻开utf-8格式的文件并读取utf-8字符串后,解码变成unicode对象。

但是会把附加的三个字符同样进展转换,变成一个unicode字符,字符的数据值为“\xFF\xFE〞。

这个字符不能被打印。

编码的时候需要跳过这个字符。

翻开unicode格式的文件后,得到的字符串正确。

这时候适用utf-16解码,能得到正确的unicdoe对象,可以直接使用。

多余的那个填充字符在进展转换时会被过滤掉。

翻开ansi格式的文件后,没有填充字符,可以直接使用。

结论:

读写使用生成的文件没有任何问题,但是在处理由notepad生成的文本文件时,如果该文件可能是非ansi编码,需要考虑如何处理填充字符。

1.6在数据库中使用中文

刚刚接触,我用的数据库是mysql。

在执行插入、查

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1