资讯专栏INFORMATION COLUMN

编码-1

IamDLY / 579人阅读

摘要:关于的参考知乎上的一个回答传送门以我自己的理解就是首先得分清楚编码问题在不同的环境中,编码是不同的。但是如果换成的是知乎的话,则表示的是将这个汉字用编码的形式存放。

文章启发来源:

cnblogs

阮一峰

知乎

字符编码方式

note from wiki:

从维基百科上得到的一些理解,一个字符的unicode编码是确定的,但是在传输过程中,由于不同系统平台的设计不一致,所以对unicode编码的实现方式是有所不同的。unicode的实现方式成为unicode转换格式(简称UTF)例如对于一个包含基本7位ASCII字符的unicode文件,如果都使用2字节的原unicode编码传输,会造成浪费。对于这种情况可以使用UTF-8编码,它是一种变长编码,对于基本ASCII字符仍然采用7位编码表示,占用一个字节。
意思其实就是,unicode规定了符号的二进制代码的符号集,但是并没有规定二进制代码应该如何存储。也就是说,在计算机的存储中,一个字符的存放方式并不一定会与它的unicode编码一致。这是因为采用了不同的编码方式所导致的。

自己整理的一些背景:

编码一开始是使用ASCII码来进行编码的,但是这个编码方式是针对英文为基础的国家的。后来,各个地区因为各自的需要,开始使用127位以后的扩展位。比如中国,因为几万个汉字,所以单靠单个127位是根本不够的,所以就规定,使用高于127位的两个字节来表示汉字。当然也就顺便把原来的一些其他扩展西方字符给出重新编码了。即,全角字符(半角字符可类推)GB2312。
后来标准随着发展,GBK变成了GB18030,即,只要第一个字节表示的十六进制数大于127,就表示汉字的开始。(DBCS,双字节字符。台湾地区的BIG5)。
后来unicode开始制定了,它的制定标准在上面的引用中可以看到,使用的是两个字节来表示字符。因此在unicode标准里,无论是汉字的全角字符还是英语的半角字符,都是一个字符,两个字节。但是unicode如何在网络上传播也是一个问题。于是,便有了UTF。UTF与unicode的转换关系如下:

note:

    0000 0000-0000 007F | 0xxxxxxx
    0000 0080-0000 07FF | 110xxxxx 10xxxxxx
    0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
    0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

其中的x是要用左边的十六进制码转化为二进制码后,代替相关的位。UTF-8的编码规则很简单,只有二条:

    1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
    2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

在查阅了几篇blog后,举个例子:比如说你现在的file用的是编辑器等(比如说是windows上的记事本,且设置它为ASCIIunicode(其实是带BOM的utf-8))默认的编码方式,那么存储的时候用的就是这种编码方式对应的在硬盘中的存储方式。比如说,此刻我用sublime 3打开,而且我的sublime 3 中只有utf系列和一些西文字体的编码方式,那么如果打开的文件用的是ASCII保存的文件,则此时会显示的乱码;而如果使用的是unicode的编码方式,也是能打开的,而且不会出现乱码的情况。
在终端或者编辑器中,如果没有进行特殊声明的话,就会使用它们默认的编码格式进行编码,或者是GBK或者是UTF,如果是ascii的话,汉字字符是无法存储的,因为没有配套的编码。所以一般能显示汉字的地方,使用的是GBK等等编码格式,要转码的话,先转换为unicode,然后再转换为其他东西。

关于python的encoding

参考知乎上的一个回答传送门

以我自己的理解就是:

首先得分清楚编码问题,在不同的环境中,编码是不同的。在终端的情况下,(windows 中是cmd,ubuntu 下的terminal,远程登录是xshell),所以他们的编码是不同的。shell环境下,windows的编码是GBK,ubuntu一般是utf-8。-------在文本编辑的情况下,与上面的情况类似,是根据编辑器的情况决定的.

在python中的情况是,unicode(A,B)的意思是用B的编码方案将A解码,并将结果返回为unicode字符串。所以一般在出现UnicodeDecodeError时候,错误的来源应该就是:

文件保存时的编码方式是编辑器默认的保存方式,而在运行环境中默认的编码方式与该文件方式并不相同,很有可能是有非ANIS的字符出现所致。因为环境无法编码该文件。

在文件保存的时候,带有BOM 。BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。
所以啊,最后在文件的头里面需要加入utf-8的说明,最好不要用BOM。

一点有意思的扩展,在pythonIDE中 两种终端下的显示
# 环境是sublime 3
    1 >>> u"知乎".encode("utf-8")
    2 "xe7x9fxa5xe4xb9x8e"
    3 >>> u"知乎".encode("gb2312")
    4 "xd6xaaxbaxf5"
    5 >>> "知乎".encode("utf-8")
    Traceback (most recent call last):
        File "", line 1, in 
    UnicodeDecodeError: "ascii" codec can"t decode byte 0xe7 in position 0: ordinal not in range(128)
   7 >>> "知乎"
     "xe7x9fxa5xe4xb9x8e"
   8 >>> u"知乎"
     u"u77e5u4e4e"
   9 >>> u"知乎".encode("utf-8").decode("utf-8")
     u"u77e5u4e4e"    
   
# 环境是windows:
    >>>"知乎"
    "xd6xaaxbaxf5"
    >>>u"知乎"
    u"u77e5u4e4e"
    >>> u"知乎".encode("utf-8")
    "xe7x9fxa5xe4xb9x8e"
    >>> u"知乎".encode("gb2312")
    "xd6xaaxbaxf5"
    
    #还是补充一下举这个例子的本意:
    #从第七行(数字标出的,以下也是一样)以及第一二行中可以看出,两个输出结果是相同的,第一行说明  将    u"知乎"  unicode字符串按照utf-8的编码方式进行编码,并以字节串的形式输出来。
    #但是如果换成的是 u"知乎" 的话,则表示的是将这个汉字用unicode编码的形式存放。(猜测是自动调用了encode方法)。所以呢,第九行意思是将utf-8编码的字符串用utf-8解码出来。
    #下面又在windows上补充了下,可以看出在不同的终端下,使用的编码方式可能是不同的,比如在windows上就有可能是,当输入汉字的时候,终端用gbk的编码方式将汉字编码。

最后再贴一个链接参考blog

总结

在这两天的调试过程中,开始将unicode的相关知识模块化,所以在此也特地写下这些东西,作为一个总结。在写代码的时候,如果一个文件中有超过ascii的字符的话,那么需要在py文件的第一行加以声明。这是因为不同的环境,不同的编译器所默认的编码字符的格式是不同的。最好能够统一以unicode字符串为基础进行转换。

update

这是一个在segmentfault网站上回答过的一个东西的链接。链接1

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38237.html

相关文章

  • 深入分析 Java Web 中的中文编码问题

    摘要:文章首发地址深入分析中的中文编码问题背景编码问题一直困扰着程序开发人员,尤其是在中更加明显,因为是跨平台的语言,在不同平台的编码之间的切换较多。 文章首发地址:深入分析 Java Web 中的中文编码问题 背景: 编码问题一直困扰着程序开发人员,尤其是在 Java 中更加明显,因为 Java 是跨平台的语言,在不同平台的编码之间的切换较多。接下来将介绍 Java 编码问题出现的根本原...

    jsyzchen 评论0 收藏0
  • 彻底理解编码

    摘要:只有彻底理解编码,遇到编码问题才知道问题的根源在哪里,并找到对应的解决办法。花一点时间去彻底消化并理解他,长远来看,对以后工作效率的提升是非常值得的。比如中国就制定了等编码规范。 只要涉及编程工作,编码是永远绕不开的问题。只有彻底理解编码,遇到编码问题才知道问题的根源在哪里,并找到对应的解决办法。花一点时间去彻底消化并理解他,长远来看,对以后工作效率的提升是非常值得的。下面是我对编码的...

    guyan0319 评论0 收藏0
  • 彻底理解编码

    摘要:只有彻底理解编码,遇到编码问题才知道问题的根源在哪里,并找到对应的解决办法。花一点时间去彻底消化并理解他,长远来看,对以后工作效率的提升是非常值得的。比如中国就制定了等编码规范。 只要涉及编程工作,编码是永远绕不开的问题。只有彻底理解编码,遇到编码问题才知道问题的根源在哪里,并找到对应的解决办法。花一点时间去彻底消化并理解他,长远来看,对以后工作效率的提升是非常值得的。下面是我对编码的...

    leoperfect 评论0 收藏0
  • 深度学习中的信息论知识详解

    摘要:散度公式交叉熵用于度量两个概率分布间的差异性信息交叉熵公式三者间的关系交叉熵和散度在机器学习中的应用信息论中有很多理论可以应用在机器学习中,其中交叉熵和散度在各类模型中出现的频率非常高。 编码 信息论研究目标: 用最少的编码表示传递信息. 举一个例子来感性认识一下: 假设两地互相通信,两地之间一直在传递A,B,C,D四类消息,那应该要选择什么样的编码方式才能尽可能少的使用资源呢? 等长...

    acrazing 评论0 收藏0
  • 深度学习中的信息论知识详解

    摘要:散度公式交叉熵用于度量两个概率分布间的差异性信息交叉熵公式三者间的关系交叉熵和散度在机器学习中的应用信息论中有很多理论可以应用在机器学习中,其中交叉熵和散度在各类模型中出现的频率非常高。 编码 信息论研究目标: 用最少的编码表示传递信息. 举一个例子来感性认识一下: 假设两地互相通信,两地之间一直在传递A,B,C,D四类消息,那应该要选择什么样的编码方式才能尽可能少的使用资源呢? 等长...

    mengera88 评论0 收藏0
  • 《Redis 设计与实现》读书笔记-Redis 对象

    摘要:编码的哈希对象使用字典作为底层实现,哈希对象中的每个键值对都使用一个字典键值对来保存。键和值的字符串长度都小于字节键值对数量小于个不能满足上面两个条件的哈希对象使用编码。 一、Redis 对象 1.1 Redis 对象简介 Redis 使用对象来表示数据库中键和值,当我们在数据库中存储一个键值对时,至少会创建两个对象,一个对象用于存储键值对的键,另一个对象用于存储键值对的值。 Redi...

    beanlam 评论0 收藏0

发表评论

0条评论

IamDLY

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<