關於漢字、亂碼和其他
01-29
原問題如下:
以下是回答:
關於編碼和亂碼的問題,我簡單講一下。
通常問這類問題的人是混淆了若干個不同的概念,並且他們自己也沒有意識到自己混淆了這些概念的。- 終端顯示字元的編碼(windows下終端是cmd,linux下是各種terminal,遠程登錄是putty或者xshell)
- shell環境的編碼。比如中文版windows用的是gbk(向下兼容gb2312),大多數linux發行版使用的是utf-8(LANG=zh_CN.UTF-8)。
- 文本文件的編碼。這個通常取決於你的編輯器,而且有的編輯器支持多種編碼的話,你可以在文本開頭位置指定編輯器使用特定編碼。比如# -*- coding: utf8 -*-,vim看到這行會默認將這個腳本認定為utf-8兼容編碼格式。
- 應用程序的內部編碼。一個字元串,作為數據只是一個位元組數組,但是作為字元的數組,就有一個解析方式。java和python的內部字元編碼是utf-16,python和java都支持用不同的編碼來對位元組數組進行decode來得到字元數組。
我在ubuntu kylin中文環境下默認terminal中做了同樣的實驗,但是結果和題主恰好相反:
看見沒有?題主和我都沒有說謊,這是為什麼呢?
因為unicode("漢字","gb2312")n
這坨代碼的含義實際上是:將這裡顯示的這坨看上去像「漢字」的東西,用gb2312解碼,轉換為unicode字元串。unicode("漢字","utf-8")類似,只不過是用utf-8解碼,轉成unicode字元串。
(註:這裡涉及到兩個概念——unicode字符集和utf-8編碼——很多時候會用混淆,一個字符集表示一堆符號,而一種編碼是用二進位表示這個字符集的一種編碼方式。同樣是unicode字符集,可以有utf-8、utf-16、utf-32等等編碼方式。)那這裡顯示的看上去像「漢字」的,到底是個什麼東西?- 如果是在我的環境下,也就是linux utf-8環境下一個utf-8顯示終端,能顯示成「漢字」的這坨東西,它實際上是以utf-8編碼的「漢」字和「字」字兩個unicode字元。它們的真實字元值就是u漢字(內碼),可以用"漢字".encode("hex")來查看當前終端下(utf-8編碼值)的十六進位碼。。所以我的命令是,將e6b189e5ad97這坨位元組數組,轉換為unicode的字元數組。——結果毫無難度,沒有錯誤,因為它本來就是utf-8編碼,所以能夠正常作為unicode字元解碼。但是unicode("漢字", "gb2312")就不一樣了,這個命令等同於「將e6b189e5ad97這坨東西,用gb2312編碼方式來解碼成字元」,但是實際上由於編碼空間並不兼容,使用gb2312編碼方式無法解碼這麼一坨奇葩的數據,所以葛屁了。
- 在題主的環境下,因為系統終端和默認文件編碼都是GBK,所以這個數實際上是
- 題主現在弄了一個文件,在開始加上了# -*- coding: utf8 -*-這下編輯器看到了,知道這文件是utf-8的了。所以編輯器對讀入的一坨坨位元組用utf-8來解碼,對於輸出到磁碟的漢字也用utf-8來編碼。所以你在文件裡面看到的看上去像「漢字」的東西,就和第一種情況下想同了,當然代碼就跑得通。順便說一下,如果編輯器無視行首這行編碼聲明,或者編輯器無法支持utf-8格式,那麼你弄好的文件在那個編輯器下就會顯示亂碼,多麼簡單的道理啊。
- 終端和環境的編碼一致(本機通常是一致的,不一致常常出現在遠程登錄);如果不一致就需要有編輯器或者文本閱讀器做一個兼容兩者的轉換。
- 編輯器能夠認識文本編碼
- 系統擁有能顯示這種字元的字體。
推薦閱讀:
※人機對戰初體驗:Python實現四子棋遊戲
※GitHub排第一的語言為什麼是js?
※學習編程感覺吃力怎麼辦?
※為什麼你需要知道介面的基本原理
※200行代碼實現web框架(三):動手寫個模板引擎