精华内容
下载资源
问答
  • 中文字符编码
    千次阅读
    2017-06-06 20:18:46

    转载
    http://blog.csdn.net/yulongli/article/details/22894645

    作为程序员,在日常的工作中总会遇到编码的知识。尤其是在前后台交互的过程中,字符编码如影随行。如果多个平台的字符编码不一致,需要相互转化的话,很有必要了解一下编码的工作原理。

    网上有太多关于编码的知识了,在此我尽量按照我对编码的理解描述的简单易懂。

    1,ASCII码

    在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位是一个bit,有0和1两种状态。8个bit构成一个字节,也就是byte。这就是bit和byte的区别。

    在日常使用中,存储的单位一般是byte,比如说到一个文件大小是2k,是说这个文件占用了2048个byte;一个内存条的容量为256M,说明该内存可以存储256*1024*1024个byte。网络传输的单位是bit,我们平常说到网络下行带宽1M,是说此网络在最好的情况下可以同时下载速度是每秒1024*1024个bit,换算成字节的话就是128k/s。

    0和1各代表一个状态,一个byte有8个bit,总共可以表示2的8次方=256个状态。若是每个状态对应一个符号,一个byte可以表示256个符号,也就是从0000000到11111111。

    在上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这就是大名鼎鼎的ASCII码了,一直沿用至今。此后虽然出现了各种各样的编码,但基本上都是兼容ASCII码的。

    但ASCII码一共只规定了128个字符的编码,比如空格”SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。

    2,GB2312

    英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。我们就以中文做例子,中国的汉字有10万左右,即使是常用字也有六七千,必须得用多个字节来表示。

    最先诞生的是GB2312编码。其编码结构不用特别了解清楚,感兴趣的可以去网上搜索专门的文档。我们只需要明白以下几点:
    1)该编码可以表示大概7000左右个字符。其中有中文及一些常见的拉丁字母等。基本可以覆盖我们日常打字使用。
    2)该编码完全兼容ASCII码,计算机去读的时候首先判断最高位,如果是0,那么这个字符只占用一个字节,表示的内容跟ASCII码表示的一样。如果该字符最高位是1,那么该字节连同下一个字节表示一个中文汉字。所以平常咱们常说的英文一个字节,中文两个字节其实是从这里来的。

    3,GBK

    两个字节最多可以表示的字符数是 2的16次方=65536,如果要求首位必须是1,那么最多可以表示 32768 个字符,但是GB2312 只用了其中的7000左右的字符。这显然是没有做到物尽其用,而且如果有些特殊的中文,GB2312根本表示不了。所以GBK就应运而生了。

    GBK 就尽量将能用到的状态都表示成中文字符了,当然最终还是有些状态没办法用(具体可以自行查找文档),最终可以表示23940个字符,其中有21003是汉字。

    GBK是完全兼容GB2312的,所以GBK的应用是很广泛的,而且从Windows95开始,Windows的中文版默认中文支持就是GBK编码。

    4,Unicode

    GBK基本解决了中文编码问题,但另外一个大问题随之而来,那就是国际化。咱们按照此方式来表示简体中文,繁体中文怎么表示?日本和韩国他们的文字也没法弄。当然他们也利用最高位来做文章,发明了big5等兼容ASCII码的编码格式,但是这几种编码之间是并不兼容的。一段GBK编码的文件在台湾友人的电脑里打开就是乱码了。

    这时候,Unicode就诞生了。

    完全弄明白Unicode的细节是非常困难的,我们也是明白以下几点就够了:
    1)Unicode编码是给世界上所有的符号都分配了一个码。GBK最多也只能表示3万多的汉字,康熙字典里面的大部分汉字都没法用GBK表示,但是Unicode就能,它可以表示这个星球上所有的符号。
    2)Unicode有UCS-2和UCS-4两种编码,2和4都是代表字节的意思,也就是说前者用两个字节表示,后者用4个字节表示。所以,UCS-2的表示范围是65536个字符,而UCS-4则可以表示超过22亿个字符,我想这真的是可以表示所有的字符了。其实日常使用我们用的只是UCS-2,一般说的Unicode编码也是只它。它包含了所有的简体中文,现用的繁体中文,火星文,以及其他国家的现用文字。古籍中的文字就得去UCS-4中去找了。

    5,UTF-8

    很遗憾,Unicode并不是完美的。不完美的地方主要有两点:
    1)不兼容ASCII码。因为Unicode是用两个字节表示,ASCII码范围内的字符都被扩充成了两个字节,前面又补了8个0。所以,如果你的电脑只支持Unicode编码的话,所有的英文资料全都没法阅读了。
    2)占用的存储变大,如果涉及到传输,所耗费的流量也会变大。中文的表现一般,英文表现最明显。纯英文文本所消耗的存储比以前增大了一倍。

    这个时候就出现了诸如UTF-8等实现方式。这里我们只讨论UTF-8,因为它是使用最广泛的。它弥补了Unicode的缺陷,所以一诞生就风靡全球了。UTF-8主要有以下几个优点。
    1)UTF-8与Unicode是一一对应的。所以UTF-8是国际化的编码方式。
    2)UTF-8是针对Unicode的可变长度字符编码,最短一个字节,最长3个字节,1个字节表示的就是ASCII码,所以UTF-8是完全兼容ASCII码的。
    3)正是因为UTF-8的变长实现,解决了Unicode的存储多的问题。可能有朋友要问了,UTF-8最多需要用3个字节表示,而Unicode只需要两个,怎么能说UFT-8会省存储呢?因为目前英文是最通用的语言,大部分字符都是ASCII码。

    但UTF-8并不是一点缺点也没有,因为变长表示,所以一段UTF-8编码没法一下子算出有多少个字符。而这一点能力对于以上几种编码格式来说是轻而易举的。所以当今世界上没有最完美的字符编码,只有最合适某个场景的编码。

    更多相关内容
  • 原文链接:程序员必备:彻底弄懂常见的7种中文字符编码 文章目录一、字符编码要做什么事情?二、几种常见中文编码的关系如何?三、ASCII编码四、GB2312、GBK、GB18030编码【GB2312】【GBK】【GB18030】五、UTF8编码...

    看到很棒的文章,忍不住搬过来收藏!原作者是鹅厂大佬。我转载一下哈
    原文链接:程序员必备:彻底弄懂常见的7种中文字符编码


    程序开发常见的ASCII、GB2312、GBK、GB18030、UTF8、ANSI、Latin1中文编码到底有何不同?如果你在业务中也曾经被乱码搞晕过,不妨一起探究一下。

    一、字符编码要做什么事情?

    在计算机眼里读到的所有文字都是由0和1组成的字符串,为了能让汉字正常显示在屏幕上,我们需要做以下两件事情:

    1、给所有的汉字一个独一无二的数字编号,做一个数字编号到汉字的mapping关系(即字符集)
    2、把这个数字编号能用0和1表示出来

    这里需要说明的是,第2件事情并不是直接把数字编号用二进制表示出来那么简单,还要处理多个字连在一起的时候如何做分隔的问题。

    例如
    如果我把”腾”编为1号(二进制00000001,占1byte),把“讯”编为5号(二进制00000101,占1byte),汉字这么多,一定还有一个汉字被编为了133号(二进制00000001 00000101,占2bytes)。

    那么现在问题来了,当计算机读到00000001 00000101这一串的时候,它应该显示“腾讯”两个字还是显示那一个133号的文字?因此如何做分隔也是字符编码需要考虑的事情。

    第2件事情通常解决方案要么就是规定好每个字长度(例如所有文字都是2bytes,不够的前面用0补齐),要么就是在用0和1表示的时候,不仅需要表示出数字编码,还要暗示给计算机接下来多少个连续byte构成一个字,这个后面UTF8编码中会提到。

    我们通常所说的Unicode,其实只做了第1件事情,并且是给全世界所有语言的所有文字或字母一个独一无二的数字编码,这样只要设计一种机制做第2件事情来表示Unicode,就可以显示全球范围内任何文字了。Unicode具体对所有语言的每个字母、文字的数字编号可以从其官方网站Unicode编码表 查询。该官网一大亮点是,中文编码表的体量远远超过其他任何语言……

    (为了让文章易懂,我暂时舍弃一些晦涩概念。晦涩地讲,现代字符编码模型其实分5个层次,可以参考链接了解:Unicode Technical Report #17 ,不在我们讨论范围内了)

    二、几种常见中文编码的关系如何?

    几种常见中文编码之间存在兼容性,一图胜千言
    在这里插入图片描述

    所谓兼容性可以简单理解为子集,同时存在也不冲突,不会出现上文所说的不知道是“腾讯”还是133号文字的情况。

    图中我们可以看出,ASCII被所有编码兼容,而最常见的UTF8与GBK之间除了ASCII部分之外没有交集,这也是平时业务中最常见的导致乱码场景,使用UTF8去读取GBK编码的文字,可能会看到各种乱码。而GB系列的几种编码,GB18030兼容GBK,GBK又兼容GB2312,下文细讲。

    三、ASCII编码

    ASCII编码每个字母或符号占1byte(8bits),并且8bits的最高位是0,因此ASCII能编码的字母和符号只有128个。有一些编码把8bits最高位为1的后128个值也编码上,使得1byte可以表示256个值,但是这属于扩展的ASCII,并非标准ASCII。通常所说的标准ASCII只有前128个值!

    ASCII编码几乎被世界上所有编码所兼容(UTF16和UTF32是个例外),因此如果一个文本文档里面的内容全都由ASCII里面的字母或符号构成,那么不管你如何展示该文档的内容,都不可能出现乱码的情况。
    在这里插入图片描述

    四、GB2312、GBK、GB18030编码

    GB全称GuoBiao国标,GBK全称GuoBiaoKuozhan国标扩展。GB18030编码兼容GBK,GBK兼容GB2312,其实这三种编码有着非常深厚的渊源,我们放在一起进行比较。

    【GB2312】

    最早一版的中文编码,每个字占据2bytes。由于要和ASCII兼容,那这2bytes最高位不可以为0了(否则和ASCII会有冲突,也就只剩下一半可以编码)。在GB2312中收录了6763个汉字以及682个特殊符号,已经囊括了生活中最常用的所有汉字。(GB2312编码全表:链接)

    GB2312编码表有个值得注意的点,这个表中也有一些数字和字母,与ASCII里面的字母非常像。例如A3B2对应的是数字2(如下图),但是ASCII里面50(十进制)对应的也是数字2。他们的区别就是输入法中所说的“半角”和“全角”。全角的数字2占两个字节。

    通常,我们在打字或编程中都使用半角,即ASCII来编写数字或英文字母。特别是编程中,如果写全角的数字或字母,编译器很有可能不认识……
    在这里插入图片描述

    【GBK】

    由于GB2312只有6763个汉字,我汉语博大精深,只有6763个字怎么够?于是GBK中在保证不和GB2312、ASCII冲突(即兼容GB2312和ASCII)的前提下也用每个字占据2bytes的方式又编码了许多汉字。经过GBK编码后,可以表示的汉字达到了20902个,另有984个汉语标点符号、部首等。值得注意的是这20902个汉字还包含了繁体字,但是该繁体字与台湾Big5编码不兼容,因为同一个繁体字很可能在GBK和Big5中数字编码是不一样的。(GBK编码全表:链接)

    【GB18030】

    然而,GBK的两万多字也已经无法满足我们的需求了,还有更多可能你自己从来没见过的汉字需要编码。

    这时候显然只用2bytes表示一个字已经不够用了(2bytes最多只有65536种组合,然而为了和ASCII兼容,最高位不能为0就已经直接淘汰了一半的组合,只剩下3万多种组合无法满足全部汉字要求)。因此GB18030多出来的汉字使用4bytes编码。当然,为了兼容GBK,这个四字节的前两位显然不能与GBK冲突(实操中发现后两位也并没有和GBK冲突)。

    我国在2000年和2005年分别颁布的两次GB18030编码,其中2005年的是在2000年基础上进一步补充。至此,GB18030编码的中文文件已经有七万多个汉字了,甚至包含了少数民族文字。有兴趣的可以到国家标准委官网了解详情,链接

    GB2312,GBK,GB18030都是采取了固定长度的办法来解决字符分隔(即前文所提的第2件事情)问题。GBK和GB2312比ASCII多出来的字都是2bytes,GB18030比GBK多出来的字都是4bytes。至于他们具体是如何做到兼容的,可以参考下图:
    在这里插入图片描述
    这图中展示了前文所述的几种编码在编码完成后,前2个byte的值域(用16进制表示)。每个byte可以表示00到FF(即0至255)。ASCII编码由于是单字节,所以没有第2位。因为GBK兼容GB2312,所以理论上上图中GB2312的领土面积也可以算在GBK的范围内,GB18030也同理。

    上图只是展示出了比之前编码“多”出来的面积。GB18030由于是4bytes编码,上图只是展示了前2bytes的值域,虽然面积最小,但是如果后2bytes也算上,GB18030新编码的字数实际上远远多于GBK。

    可以看出为了做到兼容性,以上所有编码的前2bytes做到了相互值域不冲突,这样就可以允许几种不同编码中的文字同时出现在同一个文本文件中。只要全都按照GB18030编码的规则去解析并展示文件,就不会有乱码出现。实际业务中GB18030很少提到,通常GBK见得比较多,这是因为如果你去看一下GB18030里面所编码的文字,你会发现自己一个字也不认识……
    在这里插入图片描述

    五、UTF8编码(Unicode Transformation Format)

    99%的前端写网页时都会加上<meta charset="utf-8">,99%的后端工程师新建数据库表时都会加上DEFAULT CHARSET=utf8(剩下的1%应该是忘了写)。

    之所以我们想让UTF8一统天下,就是因为UTF8可以表示出世界上所有的文字!UTF8与前面说的GB系列编码不兼容,所以如果一个文件中即有UTF8编码的文字,又有GB18030编码的文字,那绝对会有乱码。

    Unicode赋予了全世界所有文字和符号一个独一无二的数字编号,UTF8所做的事情就是把这个数字编号表示出来(即解决前文提到的第2件事情)。UTF8解决字符间分隔的方式是数二进制中最高位连续1的个数来决定这个字是几字节编码。0开头的属于单字节,和ASCII码重合,做到了兼容。

    在这里插入图片描述
    以三字节为例,开头第一个字节的”1110”,有连续三个1,说明包括本字节在内,接下来三个字节一起构成了一个文字。凡是不属于文字首字节的byte都以“10”开头,上表中标注X的位置才是真正用来表示Unicode数值的。

    这种巧妙设计,把Unicode的数值和每个字的字节数融合在一起,最坏情况是6个字节表示一个字,已经足够表示世界上所有语言的所有文字了。不过从这种表示方式也可以很显然地看出来,UTF8和GBK没有任何关系,除了都兼容ASCII以外。
    在这里插入图片描述
    举例说明,中文“鹅”字,Unicode十进制值为40517(16进制为9E45,2进制为1001 1110 0100 0101)。这个2进制值长度为12位,查询上面表格发现,二字节不够表示,四字节太长,三字节刚好,因此可以表示为 11101001 10111001 10000101,换算为16进制即E9B985,这就是“鹅”字的UTF8编码,占3字节。另外,经查询,“鹅”的GBK编码为B6EC,和UTF8的值完全不相干。

    对于中文汉字来说,所有常用汉字的Unicode值都可以用3字节的UTF8表示出来,而GBK编码的汉字基本是2字节(GB18030虽4字节但是日常没人会写那些字)。这也就导致了,如果把GBK编码的中文文本另存为UTF8编码,体积会大50%左右。这也是UTF8的一点小瑕疵,存储同样的汉字,体积比GBK要大50%。

    不过在“可表示世界上所有文字”这一巨大优势面前,UTF8的这点小瑕疵可以忽略了,所以日常开发中最常使用UTF8

    六、其他经常遇到的编码

    【ANSI编码】

    准确说,并不存在哪种具体的编码方式叫做ANSI,它只是一个Windows操作系统上的别称而已。在中文简体Windows操作系统上,ANSI就是GBK;在泰语操作系统上,ANSI就是TIS-620(一种泰语编码);在韩语操作系统上,ANSI就是EUC-KR(一种韩语编码)。并且所谓的ANSI只存在于Windows操作系统上。

    【Latin1编码(又名ISO-8859-1编码)】

    相信99%的人第一次听到Latin1都是在使用Mysql数据库的时候接触到的。Latin1是Mysql数据库表的默认编码方式。Latin1也是单字节编码方式,也就是说最多只能表示256个字母或符号,并且前128个和ASCII完全吻合。

    Latin1在ASCII基础上又充分利用了后面那128个值,赋予他们一些泰语、希腊语等字母或符号,将1个字节的256个值全部占满了。因为项目中用不到,我对这种编码的细节没兴趣了解,唯一感兴趣的是为什么Mysql选它做默认编码(为什么默认编码不是UTF8)?以及如果忘了设置Mysql表的编码方式时,用Latin1存储中文会不会出问题?
    在这里插入图片描述
    为什么默认编码是Latin1而不是UTF8?原因之一是Mysql最开始是某瑞典公司搞的项目,故默认collate都是latin1_swedish_ci。swedish可以理解为其私心,不过latin1不管是否出于私心目的,单字节编码作为默认值肯定是比多字节做默认值更不容易在插入数据时报错。

    既然Latin1为单字节编码,并且将1个字节的所有256个值全部占满,因此理论上把任何编码的值塞到Latin1字段都是可以存的(无非就是显示乱码而已)。

    假设默认为UTF8这一多字节编码,在用户误把一个不使用UTF8编码的字符串存进去时,很有可能因为该字符串不符合UTF8的编码要求导致Mysql根本没法处理。这也是单字节编码的一大好处:显示可以乱码,但是里面的数据值永远正确。

    用Latin1存储中文有没有问题?答案是没有问题,但是并不建议。例如你把UTF8编码的“讯”字(UTF8编码为0xE8AEAF,占三个字节)存入了Latin1编码的Mysql表,那么在Mysql眼里,你存入的并不是一个“讯”字,而是三个Latin1的字母(0xE8,0xAE,0xAF)。本质上,你存的数据值依然是0xE8AEAF,这种“欺骗”Mysql的行为并没有导致数据丢失,只不过你需要注意读取出来该值的时候,自己要以UTF8编码的方式显示出来,要不然就是乱码。

    因此,用Latin1存任何文字技术上都可以,但是经常会导致数据显示乱码。通常的解决方案,就是让UTF8一统天下,建表的时候就声明charset为utf8。

    文章最后,遗留一个问题。既然有这么多编码形式,如果给定一个文本文件,不告诉你是什么编码,如何用程序进行检测?比较有代表性的编码检测库为python的chardet,其具体的原理,且待下回分解~

    展开全文
  • 计算机中目前最普遍使用的汉字字符编码是ASCII码,它是用七位二进制数进行编码的,可表示128个字符。ASCII码是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。计算机中目前最普遍使用的汉字...

    计算机中目前最普遍使用的汉字字符编码是ASCII码,它是用七位二进制数进行编码的,可表示128个字符。ASCII码是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。

    430d6d1068e6119bd1df0a0c6d285384.png

    计算机中目前最普遍使用的汉字字符编码是ASCII码。

    (相关推荐:windows)

    目前在微型机中最普遍采用的字符编码是ASCII码(美国标准信息交换码),它是用七位二进制数进行编码的,可表示128个字符。

    相关介绍:

    ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符。

    展开全文
  • 解决python的中文字符编码问题

    万次阅读 2018-07-15 17:00:23
    摘要:最近在做自然语言处理相关的项目,发现中文编码的问题实在需要好好学习下,我用python为例,简单介绍下python编程时如何处理好中文编码的问题。

    摘要:最近在做自然语言处理相关的项目,发现中文编码的问题实在需要好好学习下,我用python为例,简单介绍下python编程时如何处理好中文编码的问题。

    关键字:自然语言处理, 字符编码, python


    1. 从字符编码谈起

    讲真,字符编码是很大的一块内容,单用一篇博客是完全讲不完的。这里借用一下大佬的文章:字符编码笔记:ASCII,Unicode 和 UTF-8 - 阮一峰的日志

    看完上面的那篇文章之后,相信你对字符编码有了一定的认识。在中文的自然语言处理中,最常遇到的是ASCII,Unicode,UTF-8,GB2312,GBK等。这几种编码,你都可以搜索相关的文章看下,我这里就不展开介绍了。直接用几个python的程序解释下如何在python中处理字符编码的问题。

    2. 关于python的str类型和print过程

    比如一段程序:

    # -*- coding:utf-8 -*-
    
    s = "这是一段中文"  # s是str类型的变量
    print(s)
    
    # 程序输出:“这是一段中文”
    

    这段程序中的变量s就是str类型的。我们都知道计算机内部都是二进制的0和1,str类型就是这样的0和1组成的二进制字节流,也就是说这里的变量s在计算机内部是一段二进制字节,并不是字符串。

    如果你是在python的交互式编程环境中,那么你可以做个实验:

    >>> s = "这是一段中文"
    >>> s
    \xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe6\xae\xb5\xe4\xb8\xad\xe6\x96\x87
    

    \x表示这个数是十六进制数,\xe8表示这个数是十六进制数“E8”,转换为二进制为11101000,上面的“\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe6\xae\xb5\xe4\xb8\xad\xe6\x96\x87”就是变量s所代表的字节流,换句话说,就是字符串“这是一段中文”在utf-8编码格式下的二进制表示。

    这里就出现了两个问题:

    1. 变量s赋值时,一段中文字符串是怎么变成二进制字节流的?
    2. 打印变量s时,二进制字节流是怎么变成一段中文字符串的?

    首先是问题1。变量s赋值时,字符串经过某种编码方式编码(encode)成为二进制字节,再赋值给变量s。这里的“某种编码方式”由代码显式指出,代码的第一行# -*- coding:utf-8 -*-就是用来显式地告诉计算机,你在str类型赋值时,用utf-8的编码方式。

    然后是问题2。打印变量s时,二进制字节流通过某种编码方式解码(decode)为字符串。这里的“某种编码方式”由操作系统指出。我用的ubuntu系统使用的是utf-8的编码方式。

    注意体会编码解码这两个词的不同。编码方式和解码方式一样,才能正常print,否则显示的是乱码。

    可能你还是不太明白,我们用上面的程序再做一组实验。因为每台电脑的命令行的编码方式不一样,我用的是ubuntu的系统,编码格式是utf-8,我以我的电脑为例来讲解。同时,注意实验要在命令行的状态下进行。有些ide比较智能,会自动更换输出环境的编码格式,达不到实验效果。

    第一个程序和上面的一样,我们来看下效果:

    # -*- coding:utf-8 -*-
    
    # 命令行的编码方式为utf-8
    
    s = "这是一段中文"  # s是str类型的变量,计算机把字符串以utf-8格式编码成二进制字节,赋值给s
    
    print(s)    # s是str类型的变量,计算机读取s(也就是读取出二进制字节),然后以utf-8格式解码为字符串
    
    # 程序输出:“这是一段中文”
    

    然后,我们改动第一行:

    # -*- coding:GBK -*-
    
    # 命令行的编码方式为utf-8
    
    s = "这是一段中文"  # s是str类型的变量,计算机把字符串以GBK格式编码成二进制字节,赋值给s
    
    print(s)    # s是str类型的变量,计算机读取s(也就是读取出二进制字节),然后以utf-8格式解码为字符串
    
    # 程序输出:一段乱码
    

    我们再做第三个实验:

    # -*- coding:utf-8 -*-
    
    # 命令行的编码方式为GBK
    
    s = "这是一段中文"  # s是str类型的变量,计算机把字符串以utf-8格式编码成二进制字节,赋值给s
    
    print(s)    # s是str类型的变量,计算机读取s(也就是读取出二进制字节),然后以GBK格式解码为字符串
    
    # 程序输出:一段乱码
    

    我想你应该能理解这三个程序之间的区别。

    2. 关于unicode类型

    unicode类型是python中的一种字符串类型,在计算机内也是二进制字节。不过不同于str是单纯的二进制字节,unicode类型特指由ucs2或者ucs4编码格式编码的二进制字节。

    如果你在python的交互式编程环境中,你可以做个实验:

    >>> s = u"这是一段中文"    # 这边多了个u,表示变量s为unicode变量
    >>> s
    u'\u8fd9\u662f\u4e00\u6bb5\u4e2d\u6587'
    

    可以看到,和上面str类型的实验结果的\x不一样了,这里出现的是\u\u代表了在unicode编码表中的位置,比如\u8fd9就代表unicode编码表中8fd9这个位置的字符。

    python中unicode类型的变量是作为一个中转站存在的。比如你要把一段字符串从utf-8编码转为GBK编码,你需要做的是:

    # -*- coding:utf-8 -*-
    
    s = "这是一段中文"  # s是str类型的变量,计算机把字符串以utf-8格式编码成二进制字节,赋值给s
    
    s.decode("utf-8")   # 二进制字节s以utf-8格式解码到unicode,解码后s从str类型变为unicode类型
    
    s.encode("GBK")     # unicode类型的变量s被以GBK格式编码为二进制字符串,编码后变量s从unicode类型变为str类型
    
    # 程序输出:一段乱码
    

    反过来,要把一个GBK编码的字符串转为utf-8也一样,要以unicode作为中转站。

    3. sys.setdefaultencoding(‘utf-8’)

    网上一些教程会教你,在遇到中文编码问题的时候,在代码的开头加上这几句:

    # -*- coding:utf-8 -*-
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    

    你一试,还真的解决了问题,但你不知道这几句话有什么用。

    第一句# -*- coding:utf-8 -*-上一段已经说了,是为了显式地说明代码是由utf-8格式编码的,如果你不加的话,一般来说是采用默认编码ascii。ascii不支持中文,你的代码中有任何中文就会出错。

    后面三句,最重要的是sys.setdefaultencoding('utf-8'),它的目的是修改默认的解码方式为utf-8。

    看下面的实验:

    # -*- coding: utf-8 -*- 
    s = '中文字符'  # s是字符串经过utf-8编码格式编码后的二进制字节,str类型
    s.encode('GBK') # s是二进制字节,它不会直接encode。python会首先调用decode,将s从str类型变为unicode格式,再用GBK编码为str类型
    

    你可以使用以下代码获取python默认的解码方式:

    import sys
    print(sys.getdefaultencoding())
    

    假如你获取到的默认解码方式为ascii。那么:

    # -*- coding: utf-8 -*- 
    s = "这是一段中文"  # s是字符串经过utf-8编码格式编码后的二进制字节,str类型
    s.encode("GBK") # s是二进制字节,它不会直接encode。python会首先调用decode,将s从str类型变为unicode格式,再用GBK编码为str类型
    
    # 如果你的默认解码方式为ascii,那么上面一句话在实际执行时,相当于下面这句话
    s.decode("ascii").encode("GBK")
    

    显然,程序会报错:UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe4 in position 。

    解决方法1,显示地指明解码格式:

    # -*- coding: utf-8 -*- 
    s = "这是一段中文" 
    
    s.decode("utf-8").encode("GBK") 
    

    解决方法2,修改默认解码方式:

    # -*- coding: utf-8 -*- 
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    s = "这是一段中文" 
    
    s.encode("GBK") 
    

    你应该能从这几个实验中明白sys.setdefaultencoding('utf-8')的作用。

    4. 检验学习成果

    python常见编码错误集合 - 妙音的博客

    看看上面链接的博客里所列举的几个错误示例,现在你是否能够一眼就找出错误点,并给出解决方法呢?

    展开全文
  • 为大家提供Python的UTF-8编码查询表,大家可以对照左列的编码查询右列的汉字。 例:\u4e00对应汉字“一”
  • 纯js对字符串进行gb2312编码解码,如“中国”编码后成为:“%D6%D0%B9%FA”,很好用的
  • Python文件默认的编码格式是ascii ,无法识别汉字,因为ascii码中没有中文。 所以py文件中要写中文字符时,一般在开头加 # -*- coding: utf-8 -*- 或者 #coding=utf-8。 这是指定一种编码格式,意味着用该编码存储...
  • 下面小编就为大家带来一篇C#将Unicode编码转换为汉字字符串的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 《信息交换用汉字编码字符集》是由中国国家标准总局1980年发布,1981年5月1日开始实施的一套国家标准,标准号是GB2312-1980。GB2312编码适用于汉字处理、汉字通信等系统之间的信息交换,通行于中国大陆;新加坡等地...
  • c++程序中文字符编码初探

    千次阅读 2019-08-29 21:45:21
    前几天从一个PDF文档中复制...于是在网上恶补了一些字符编码的知识,基本搞懂了中文字符在计算机中的编码处理方法,下面以windows系统c++程序处理中文字符的方法来举例说明。 首先介绍一下字符编码的基础知识。 a...
  • 常见的汉字字符编码

    万次阅读 2017-07-13 16:59:27
    以下是常见的汉字字符编码: GB2312编码:1981年5月1日发布的简体中文汉字编码国家标准。GB2312对汉字采用双字节编码,收录7445个图形字符,其中包括6763个汉字。 BIG5编码:台湾地区繁体中文标准字符集,采用双...
  • 什么是计算机中应用最普遍的字符编码发布时间:2020-08-07 11:15:28来源:亿速云阅读:127作者:Leah什么是计算机中应用最普遍的字符编码?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想...
  • 中文字符集与编码转换

    千次阅读 2019-04-18 11:45:27
    字符集,windows 又称代码页, 与操作系统的当前字符集项不匹配时,会显示乱码。 常见的简体中文字符集( windows 代码页 936 ) GB18030: 1字节 兼容 ascii 字符 2 字节 普通中文 ...
  • 常见字符编码介绍

    千次阅读 2022-03-25 09:48:21
    ASCII是美国(国家)信息交换标准(代)码,一种使用7个或8个二进制位进行编码的方案,最多可以给256(2^80)个字符 (包括字母、数字、标点符号、控制字符及其他符号)分配(或指定)数值。基本的 ASCII 字符集共有 128 个...
  • 字符编码windows notepad、windows notepad++和sublime text的字符编码显示区别: windows notepad notepad++ sublime text ANSI ANSI GB2312 Unicode UCS-2 LE BOM UTF-16LE Unicode big endian UCS-2 BE...
  • 在现在的互联网,字符编码是互联网信息交互的一个重要基础,各种语言都有支持信息编码的机制,Python也不例外。Python除了字符编码之外,对于字节码和字符串两种类型有严格区分,字符串是本地可以读取的信息,字节码...
  • 在开发过程中,字符编码始终是程序猿和程序媛们绕不开的一个话题。这里简要整理下有关字符编码的知识,供列位看官茶余饭后消遣:)本回答尽量直观地介绍相关概念,不纠缠相关规定的细节,以使读者能对字符编码有着更...
  • 中文字符UTF8编码

    千次阅读 2021-11-04 15:47:41
    中文字符UTF8编码 UTF8编码是广义上unicode实现形式之一。中文字符到utf8编码的一般过程:中文字符->unicode->UTF8。 示例 以中文字符“哈”为例: 1.中文字符“哈”的unicode为“54c8”,对应的二进制表示...
  • JAVA中文字符编码问题详解

    千次阅读 2018-05-11 10:44:51
    JAVA中文字符编码问题详解 JAVA的中文字符乱码问题一直很让人头疼。特别是在WEB应用中。网上的分析文章和解决方案都很多,但总是针对某些特定情况的。很多次遇到乱码问题后,经过极为辛苦的调试和搜索资料后终于...
  • 中文字符编码的相互转换(一)

    万次阅读 多人点赞 2014-04-03 20:46:04
    尤其是在前后台交互的过程中,字符编码如影随行。如果多个平台的字符编码不一致,需要相互转化的话,很有必要了解一下编码的工作原理。 网上有太多关于编码的知识了,在此我尽量按照我对编码的理解描述的简单易懂。...
  • 计算机常用字符编码

    千次阅读 2021-06-29 14:32:50
    是基于罗马字母表的一套电脑编码系统,它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO 646。 国标准信息交换码的英文简称,是计算机中用二进制表示字母、数字、符号...
  • 中文汉字字符、标点和unicode、GBK的编码对应表
  • QT:QString 字符串和中文字符编码

    千次阅读 2017-04-04 00:08:43
    QString 字符串和中文字符编码 QT内部的编码方式 Unicode (utf-16) linux平台默认使用:utf-8 windows平台默认使用:gbk2312/gbk/gbk18030 QString内部使用Unicode编码,使用双引号的字符串,通过转换构造函数,...
  • 小技巧1:CSS中出现的乱码都是由于CSS字符编码与页面的字符编码不一致所引起的,因此最直接的方法就是使字符编码一致。将CSS指定编码类型,例:@charset utf-8;(指定编码类型为utf-8,须写在CSS文件第一行) 小技巧2...
  • golang中文字符编码转换

    万次阅读 2017-12-08 21:38:56
    golang处理中文时默认是utf8,当遇到其他如GBK字符是就会出现乱码,此处介绍golang 官方golang.org/x/text/encoding/simplifiedchinese包下的编码转换 package main import "golang.org/x/text/encoding/...
  • 汉字字符编码查询 unicode编码查询

    万次阅读 2018-09-13 09:04:06
    GB2312编码:1981年5月1日发布的简体中文汉字编码国家标准。GB2312对汉字采用双字节编码,收录7445个图形字符,其中包括6763个汉字。 BIG5编码:台湾地区繁体中文标准字符集,采用双字节编码,共收录13053...
  • 字符编码

    千次阅读 2020-07-15 19:47:50
    一、了解字符编码表 一:计算机基础知识 1、程序运行与三大核心硬件(cpu,内存,硬盘)的关系: 任何一个程序都是先存放于硬盘上的,必须先由硬盘读取到内存,之后cpu去内存中取值然后执行 2、程序运行过程中产生的...
  • GB 18030-2005 信息技术 中文编码字符
  • Java字符编码设置总结

    千次阅读 2021-02-13 00:04:59
    1、eclipse workspace中的字符编码:windows->Preferences->general->Workspace以后新建立工程其属性对话框中的Text file encoding即为UTF-8,这个也是安装完Eclipse之后应该立刻做的第一件事,但是这种...
  • 字符编码基础知识- Unicode,UCS,GBK,GB2312,UTF-8最近遇到一个Unicode和UTF-8关系比较的问题,之前在处理中文显示时也遇到过类似的问题,于是花时间学习了一下,在此做个总结归纳,借以加深理解。(本文多数内容均...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 431,831
精华内容 172,732
关键字:

中文字符编码