摘要:关于的参考知乎上的一个回答传送门以我自己的理解就是首先得分清楚编码问题在不同的环境中,编码是不同的。但是如果换成的是知乎的话,则表示的是将这个汉字用编码的形式存放。
文章启发来源:
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上的记事本,且设置它为ASCII,unicode(其实是带BOM的utf-8))默认的编码方式,那么存储的时候用的就是这种编码方式对应的在硬盘中的存储方式。比如说,此刻我用sublime 3打开,而且我的sublime 3 中只有utf系列和一些西文字体的编码方式,那么如果打开的文件用的是ASCII保存的文件,则此时会显示的乱码;而如果使用的是unicode的编码方式,也是能打开的,而且不会出现乱码的情况。
在终端或者编辑器中,如果没有进行特殊声明的话,就会使用它们默认的编码格式进行编码,或者是GBK或者是UTF,如果是ascii的话,汉字字符是无法存储的,因为没有配套的编码。所以一般能显示汉字的地方,使用的是GBK等等编码格式,要转码的话,先转换为unicode,然后再转换为其他东西。
参考知乎上的一个回答传送门
以我自己的理解就是:
首先得分清楚编码问题,在不同的环境中,编码是不同的。在终端的情况下,(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。
# 环境是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
总结update在这两天的调试过程中,开始将unicode的相关知识模块化,所以在此也特地写下这些东西,作为一个总结。在写代码的时候,如果一个文件中有超过ascii的字符的话,那么需要在py文件的第一行加以声明。这是因为不同的环境,不同的编译器所默认的编码字符的格式是不同的。最好能够统一以unicode字符串为基础进行转换。
这是一个在segmentfault网站上回答过的一个东西的链接。链接1
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/38237.html
摘要:文章首发地址深入分析中的中文编码问题背景编码问题一直困扰着程序开发人员,尤其是在中更加明显,因为是跨平台的语言,在不同平台的编码之间的切换较多。 文章首发地址:深入分析 Java Web 中的中文编码问题 背景: 编码问题一直困扰着程序开发人员,尤其是在 Java 中更加明显,因为 Java 是跨平台的语言,在不同平台的编码之间的切换较多。接下来将介绍 Java 编码问题出现的根本原...
摘要:只有彻底理解编码,遇到编码问题才知道问题的根源在哪里,并找到对应的解决办法。花一点时间去彻底消化并理解他,长远来看,对以后工作效率的提升是非常值得的。比如中国就制定了等编码规范。 只要涉及编程工作,编码是永远绕不开的问题。只有彻底理解编码,遇到编码问题才知道问题的根源在哪里,并找到对应的解决办法。花一点时间去彻底消化并理解他,长远来看,对以后工作效率的提升是非常值得的。下面是我对编码的...
阅读 1027·2023-04-26 02:02
阅读 2370·2021-09-26 10:11
阅读 3522·2019-08-30 13:10
阅读 3706·2019-08-29 17:12
阅读 687·2019-08-29 14:20
阅读 2168·2019-08-28 18:19
阅读 2171·2019-08-26 13:52
阅读 933·2019-08-26 13:43