摘要:關于的參考知乎上的一個回答傳送門以我自己的理解就是首先得分清楚編碼問題在不同的環境中,編碼是不同的。但是如果換成的是知乎的話,則表示的是將這個漢字用編碼的形式存放。
文章啟發來源:
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
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38237.html
摘要:文章首發地址深入分析中的中文編碼問題背景編碼問題一直困擾著程序開發人員,尤其是在中更加明顯,因為是跨平臺的語言,在不同平臺的編碼之間的切換較多。 文章首發地址:深入分析 Java Web 中的中文編碼問題 背景: 編碼問題一直困擾著程序開發人員,尤其是在 Java 中更加明顯,因為 Java 是跨平臺的語言,在不同平臺的編碼之間的切換較多。接下來將介紹 Java 編碼問題出現的根本原...
摘要:只有徹底理解編碼,遇到編碼問題才知道問題的根源在哪里,并找到對應的解決辦法?;ㄒ稽c時間去徹底消化并理解他,長遠來看,對以后工作效率的提升是非常值得的。比如中國就制定了等編碼規范。 只要涉及編程工作,編碼是永遠繞不開的問題。只有徹底理解編碼,遇到編碼問題才知道問題的根源在哪里,并找到對應的解決辦法?;ㄒ稽c時間去徹底消化并理解他,長遠來看,對以后工作效率的提升是非常值得的。下面是我對編碼的...
閱讀 1061·2023-04-26 02:02
閱讀 2401·2021-09-26 10:11
閱讀 3553·2019-08-30 13:10
閱讀 3743·2019-08-29 17:12
閱讀 720·2019-08-29 14:20
閱讀 2187·2019-08-28 18:19
閱讀 2230·2019-08-26 13:52
閱讀 954·2019-08-26 13:43