還是先從乙個故事開始吧。
jonathan swift的《格利佛遊記》:lilliput和blefuscu這兩個強國在過去的36個月中一直在苦戰。戰爭的原因:大家都知道,吃雞蛋的時候,原始的方法是打破雞蛋較大的一端,可以那時的皇帝的祖父由於小時侯吃雞蛋,按這種方法把手指弄破了,因此他的父親,就下令,命令所有的子民吃雞蛋的時候,必須先打破雞蛋較小的一端,違令者重罰。然後老百姓對此法令極為反感,期間發生了多次叛亂,其中乙個皇帝因此送命,另乙個丟了王位,產生叛亂的原因就是另乙個國家blefuscu的國王大臣煽動起來的,叛亂平息後,就逃到這個帝國避難。據估計,先後幾次有11000餘人情願死也不肯去打破雞蛋較小的端吃雞蛋。這個其實諷刺當時英國和法國之間持續的衝突。danny cohen一位網路協議的開創者,第一次使用這兩個術語指代位元組順序,後來就被大家廣泛接受。
在桌面上新建乙個記事本檔案,在裡面輸入聯通兩個字,然後儲存,關閉,再開啟,「聯通」二字變成了��ͨ有人說這就是移動比聯通強盛的原因。我也是醉了。「聯通」的內碼是0xc1(1100 0001), 0xaa(1010 1010),0xcd(1100 1101),0xa8(1010 1000)這兩個字的起始部分的是"110"和"10",正好與utf8規則裡的兩位元組模板是一致的,於是再次開啟記事本時,記事本就誤認為這是乙個utf8編碼的檔案……當文件中所有字元(假設編碼:aabb)都在(c0≤aa≤df,80≤bb≤bf)這個範圍的時候都會遇到這個問題……而且像一絲,一兩,一些,一位,一位女士,一俟,一偏,一元,一準,一力,一匹,一十,一千,一千元,一去,一雙,也會出錯的。
根源還是windows弄混了utf編碼和gb編碼的原因。
windows記事本儲存方法
四個選項:ansi,unicode,unicode big endian 和 utf-8。
1)ansi是預設的編碼方式。對於英文檔案是ascii編碼,對於簡體中文檔案是gb2312編碼(只針對windows簡體中文版,如果是正體中文版會採用big5碼)。
2)unicode編碼指的是ucs-2編碼方式,即直接用兩個位元組存入字元的unicode碼。這個選項用的little endian格式。
3)unicode big endian編碼與上乙個選項相對應。
4)utf-8編碼,
在最開始的故事裡說到了大小端。假設乙個數字是int型,它需要32位儲存,用十六進製制寫為0x12 34 56 78.那麼這幾個數字應該是12在乙個位元組,34在乙個位元組,56 78各在乙個位元組。那麼問題來了。記憶體位址是從小到大的,該怎麼放呢,12在高位上,權重大,假設在四個位元組中儲存。這就有順序和逆序了。如圖
小端呢,高位在後面便於計算,比如4000位元組值乘以1,4001乘以256,這樣順序很好算。而大端呢,讀取字元方便,從前往後12 34 56 78比起小端的 78 56 34 12順多了吧。
大小端,從低位址往高位址走,按著順序讀下去的為大端。
一般作業系統都是小端,而通訊協議是大端的。常見cpu的位元組序
big endian : powerpc、ibm、sun
little endian : x86、dec。
windows下記事本為了方便區分各種編碼,用了bom。bom最初設計是為了解決諸如utf16兩個位元組大小端的問題,也就是先儲存高位還是低位。或者在網路傳輸協議中先傳高位還是低位。然而微軟在記事本只用也利用它來辨別編碼種類問題。所以就多了一種問你,容易出現最初吧聯通搞錯的故事了。
bom byte order mark。unicode的位元組順序 標記。utf16為u+feff。看大小端,大端為feff,小端為fffe。
utf-8 不需要 bom,儘管 unicode 標準允許在 utf-8 中使用 bom。所以不含 bom 的 utf-8 才是標準形式,在 utf-8 檔案中放置 bom 主要是微軟的習慣,把帶有 bom 的小端序 utf-16 稱作「unicode」而又不詳細說明,這也是微軟的習慣)。bom(byte order mark)是為 utf-16 和 utf-32 準備的,用於標記位元組序(byte order)。微軟在 utf-8 中使用 bom 是因為這樣可以把 utf-8 和 ascii 等編碼明確區分開,但這樣的檔案在 windows 之外的作業系統裡會帶來問題。
檔案中加了編碼順序字元 feff,如果ff開頭為小端,fe為大端。ef bb bf代表utf-8編碼。
亂碼問題
當程式用特定字元編碼解析位元組流的時候,一旦遇到無法解析的位元組流時,就會用symbol或者?�來替代。因此,一旦最終解析得到的文字包含這樣的字元,而你又無法得到原始位元組流的時候,說明正確的資訊已經徹底丟失了,嘗試任何字元編碼都無法從這樣的字元文字中還原出正確的資訊來。
?在ascii碼中為3f,因此當你傳ff接收到位元組為3f說明你的資料已經失真了。
而�是一種替代符號unicode編碼為u+fffd。65533表示這不是合法unicode編碼
字元編碼亂碼處理
python3預設編碼是unicode 而python2是ascii碼。windows環境預設是gbk編碼。1.python直譯器的預設編碼 2.python原始檔檔案編碼 3.terminal使用的編碼 4.作業系統的語言設定 一 編碼的種類 i ascii 佔1個位元組,只支援英文 ii gb2...
CSS字元編碼引起亂碼
亂碼引起的css失效原理 由於乙個中文是兩個字元組成,在編碼不一致的情況下會引發字元的 重新 組合,半個漢字的編碼字元與後面的字元組合生成新的 文字 引發原本的結束符合 變異 從而導致找不到結束符號,使得後面的css就會失效。小技巧1 css中出現的亂碼都是由於css字元編碼與頁面的字元編碼不一致所...
Qt 字元編碼 亂碼總結
cpp view plain copy qtextcodec setcodecforcstrings qtextcodec codecforname utf 8 qtextcodec setcodecforlocale qtextcodec codecforname utf 8 qtextcodec...