【原創】通俗易懂地解決中文亂碼問題(1) --- 跨平臺亂碼
本來是隻打算寫一篇關於中文亂碼的blog的,但是發現要講的東西跨度有點大,不好寫到同一篇裡面,所以分開了。
這一篇重點在編碼的理論,另一篇重點在解決問題及思路。
一、問題的開始
中文亂碼問題經常出現在實際工程中,尤其容易發生在經驗不足的團隊對問題預估不足的情況下。網站開發,社交聊天等對輸入資訊不可控的應用往往是重災區。再加上移動網際網路的火熱,新興字元和表情也開始頻繁被使用,如果不能達到足夠的支援,對使用者體驗來說是個災難。所以,在設計系統的開始,要嚴格把控字元編碼。以大體明確怎麼做是不會出錯的(嚴格按規則限制往往難以把控,並且容易漏掉被鑽空子,所以做到不出錯是出發點)。
二、Unicode
Unicode是本文的重點。
Unicode是一種通用字符集,是對字元的定義。和之對應的也有,比如 ISO 8859-1。但Unicode被廣泛使用併成為業界的標準,所以我們可以認為Unicode就是對計算機裡字元的定義,在記憶體中的表現是0,1串。
而且,Unicode的編碼很乾淨,它為 字元而非字形定義唯一的程式碼。換句話說,統一碼以一種抽象的方式(即數字)來處理字元,並將視覺上的演繹工作(例如字型大小、外觀形狀、字型形態、文體等)留給其他軟體來處理,例如網頁瀏覽器或是文書處理器。舉個例子,如 “ɑ/a”、“強/強”、“戶/戶/戸”。(引自wiki)
這樣,Unicode本身要做的任務很明確,就是合適的擴充編碼。
三、UTF-8
UTF-8是Unicode的一種實現方式,是可變長的字元編碼。與之對應的還有GBK(固定長度),Latin,UTF-16(Unicode的完全式)等等。
這些為什麼是實現方式呢?不是Unicode已經定義好了嗎?其實這也是計算機學科經常用的方法,這些不同的編碼就類似於針對Unicode的各種trick。
舉個簡單的例子,一個整形陣列A[],那麼給A[]排序這個定義就相當於Unicode。那麼是採用快排、堆排還是歸併,用正序還是倒序排列結果,這些方法就相當於編碼格式。而這些都是對這個定義的具體實現過程,但是方法不同。
因此,不論是UTF-8、GBK、Latin等,其還原的編碼結果都是同一個Unicode
四、Unicode和UTF-8的關係及轉換過程
那麼對於Unicode和UTF-8的關係,可以用上面的例子理解。不過真實情況應該是類似下面這樣的。
比如"國"字的Unicode編碼定義為 00000000 00000000 00110100 11000000 (假設)。
由於其低16位都是0,為了減少儲存和傳輸這個字在位元組上的浪費,就選擇高16位來表示。同時由於UTF-8是可變長的,所以需要標識位來標識這個編碼到底使用了幾個位元組。
所以 “國”字 對應的 UTF-8的編碼應該是 11100011 10010011 10000000(加粗的是原編碼的高16位)。
轉換公式:1110xxxx(E0-EF) 10yyyyyy 10zzzzzz,顯示標明的是標誌位)。
以下附上UTF-8的編碼方式:(引自wiki)
五、中文跨平臺亂碼及解決辦法
有了以上知識的積累,我們可以分析為什麼跨平臺會出現亂碼?明明好好的Unicode怎麼就亂了呢?
那麼很直觀我們會想到應該是編碼格式不相容。
對於windows平臺,編碼格式是GBK,對應的漢字是兩個位元組長度。對於Linux平臺,編碼格式是UTF-8,對應的漢字是3個位元組。(這裡都是預設情況)
那麼我們還用上面 排序這個例子來解釋。
比如現在Unicode用 {1,2,3}定義,GBK代表正序排列,UTF-8代表倒序排列。那麼現在Unicode在GBK下的編碼是{1,2,3},在UTF-8下的編碼是{3,2,1}。
現在由GBK編碼還原Unicode編碼,那麼正向解析GBK就是Unicode。而由UTF-8編碼還原Unicode編碼,需要逆向解析UTF-8編碼。這都是和自身對應的。
但是如果一個把GBK編碼誤認為是UTF-8,那麼逆向解析後的結果是{3,2,1}。首先這個結果不是原始的Unicode編碼,那麼其轉換的結果不是我們需要的。其次,很可能這個編碼結果在Unicode中還沒有定義,可能會出現類似空格一樣的空白符。
因此這就是跨平臺中文亂碼的原因,編碼和解碼方式出現了差別。
解決辦法:
解決辦法其實有很多種,根據自身應用的不同既可以選擇在程式碼端進行編碼的轉換(比如java的 String str = new String(str.getBytes("GBK"), "UTF-8");),也可以在輸入端進行編碼格式的調整。
不過歸結下來只有一點,即 如果當前輸入是GBK編碼,而你需要的又是UTF-8編碼,那麼:
1. 用GBK的解碼方式轉換成Unicode。
2. 使用UTF-8編碼進行編碼。
六、中文編碼一些有趣的應用
這裡我只想到了war3(感謝@殭屍的提醒)上面一些搞笑的名字(一不小心貌似暴露了什麼。。),後面想到其它還會更新的。
比如下面這個圖:
藍圈裡面的玩家名字是正常顯示的,為綠色。紅圈裡面的是藍色,相當於突破了war3的限制顯示了其它特殊顏色。
這個做法就是對應名字後面加上|r。這是一個轉義符,合理的利用了war3給使用者開放的字符集併產生了特殊效果。所以這也是我開篇說的嚴格把控字符集是很難的,控制到不出錯(比如系統亂碼)已經挺好了。
轉載請註明出處,謝謝~ http://www.cnblogs.com/xiaoboCSer/p/4175361.html
相關推薦
【原創】通俗易懂地解決中文亂碼問題(1) --- 跨平臺亂碼
本來是隻打算寫一篇關於中文亂碼的blog的,但是發現要講的東西跨度有點大,不好寫到同一篇裡面,所以分開了。 這一篇重點在編碼的理論,另一篇重點在解決問題及思路。 一、問題的開始 中文亂碼問題經常出現在實際工程中,尤其容易發生在經驗不足的團隊對問題預估不足的情況下。網站開發,社交聊天等對輸入資訊不
【原創】通俗易懂地解決中文亂碼問題(2) --- 分析解決Mysql插入移動端表情符報錯 ‘incorrect string value: '\xF0...
當然,如果只是針對解決這個Mysql插入報錯問題,本篇足夠了。 一、定位錯誤 定位錯誤絕對是至關重要的一環。我建議遇到問題耐心分析一下比較好,畢竟“不是所有的牛奶都叫特侖蘇”。 引起同一個問題的可能有很多,別人的解決方案也許並不適合自己。 那先看看問題出現在哪了,報錯如下: 發現的確
【原創】智慧合約安全事故回顧分析(1):The Dao事件
首先需要說明的一點是,這個世界上沒有絕對安全的技術。在區塊鏈發展的十年裡,各種基於區塊鏈的數字貨幣引發的安全事故層出不窮,這些安全威脅主要來源有三個方面: 自身安全機制的問題,類似智慧合約。 生態安全問題,交易所,礦池,網站等等。 使用者安全問題,包括個人賬號密碼的洩露,被釣魚等。
【原創】python3將圖片寫入mysql資料庫(一)
01.環境準備使用的包:pymysqlpymysql下載地址:https://pypi.python.org/pypi/PyMySQL#downloads02.pymysql安裝:03.mysql的blob欄位解釋:BLOB型別的欄位用於儲存二進位制資料MySQL中,BLOB
【演算法】B+樹的研讀及實現(1)
【前言】 為什麼要明白b+樹?假如大家有操作資料庫及開發有關資料庫的經驗,那麼肯定知道索引這個概念,那麼進一步問你什麼叫索引? mysql的索引就是B+樹,而其他資料庫我不太清楚,但是,b+樹是一般的索引演算法,當然,oracle、postgres等資料庫聽說也支援r樹的索
【爬蟲】手把手教你寫網路爬蟲(1)
介紹 什麼是爬蟲? 先看看百度百科的定義: 簡單的說網路爬蟲(Web crawler)也叫做網路鏟(Web scraper)、網路蜘蛛(Web spider),其行為一般是先“爬”到對應的網頁上,再把需要的資訊“鏟”下來。 為什麼學習爬蟲? 看到這裡,有人就要問了:Google、百度等
【原創】mysql 正則匹配中文&…
含中文: where name regexp '[^ -~]' 不含中文: where name not regexp '^[^ -~]' 後來說需要查詢日文 參考資料得知: utf-8 (unicode) /u4e00-/u9fa5 (中文) /x3130-/x318f (韓文) /xac00
【原創】新韭菜日記2---人性的缺點1:為什麼總是急著賣漲的,而捨不得割肉?
心理學書上寫的 為什麼總是急著賣漲的,而捨不得割肉? 前提情景:手上已經持股 行為模式:手上持有的股票,漲價後非常想賣 手上持有的股票,跌價後不想割肉 心
【原創】給定隨機數的取值範圍(最小值、最大值),且要求多次取得的隨機數最後的結果有一個固定的平均值
給定隨機數的取值範圍(最小值、最大值),且要求多次取得的隨機數最後的結果有一個固定的平均值。 演算法如下: /****** * author ztg 281099678 2018-12-06 * @param $min float 範圍最小值 * @param $max
【原創】linux spinlock/rwlock/seqlock原理剖析(基於ARM64)
# 背景 - `Read the fucking source code!` --By 魯迅 - `A picture is worth a thousand words.` --By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器,Contex-A53,雙核 3. 使用工具:S
【原創】CentOS 7搭建多例項MySQL8(想要幾個搞幾個)
起因 最近專案上開始重構,可能會用到主從加讀寫分離的情況,就想先在本地搭一個出來試試效果,結果百度一搜出來一大堆,然而自己去踩坑的沒幾個,絕大多數都是去抄的別人的內容,關鍵是實際應用中還會出錯,瀏覽器開了接近二十個標籤頁,試了好幾個都有問題,完全用不了,時間浪費了不說,還會讓你很憋屈
【原創】xenomai與VxWorks實時性對比(資源搶佔上下文切換對比)
版權宣告:本文為本文為博主原創文章,轉載請註明出處。如有問題,歡迎指正。部落格地址:https://www.cnblogs.com/wsg1100/ 可能大部分人一直好奇VxWorks與xenomai對比,實時性孰優孰劣,正好筆者最近要做一個這方面的對比。**宣告:下面資料,僅供個人參考,有不對的地方還請指
【Shiro】Apache Shiro架構之身份認證(Authentication)
trac pretty asm 安全保障 軟件測試 釋放 model tac 讀取配置文件 Shiro系列文章: 【Shiro】Apache Shiro架構之權限認證(Authorization) 【Shiro】Apache Shiro架構之集成web
【整理】軟件工程復習提綱(維護)
評價 描述 nbsp 參考 操作 text 吸引 復習 組織 章魚小年糕整理,如果有錯誤歡迎提出,若要二次修改發布,請留言,謝謝^_^! 概念 軟件維護:軟件在已經交付使用之後,為了改正錯誤或滿足新的需求修改軟件的過程。 文檔:有關計算機程序功能、設計、編制、使用的文字或圖
【原】fetch跨域請求附帶cookie(credentials)
allow src ssi ann oct o-c ech .com 頭部 HTTP訪問控制 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS 解決跨域的方式有很多種,本文介紹“跨域請
【充分利用你的Azure】將Azure用作雲計算平臺(1)
遠程 spa http pac 雲計算 學習 .com xshel 利用 本文將圍繞幾個步驟來講。 因為本人是MSP,微軟送了150刀的額度給我隨便使用。這篇文章是要講將Azure用作雲計算平臺,對於我來說,我是做機器學習的,那麽Azure就要有機器學習的平臺。 本文的目的
【gulp】前端自動化工具---gulp的使用(一)------【凡塵】
app 一起 dex 前端自動化 指定 sass css 文件的 等待 什麽是gulp? 基於node的自動化構建工具 擴展:開發的時候分為2個節點一個是開發階段 另一個是部署階段 開發階段:源文件不會被壓縮
【AI基礎】python:openCV——處理鼠標事件(1)
python:opencv 處理鼠標 一、用戶通過鼠標對圖像視窗最常見的操作有: 左鍵單擊按下 左鍵單擊擡起 左鍵按下拖動 鼠標指針位置移動 二、單次單擊操作響應事件及順序 Opencv中setMouseCallback()創建了一個鼠標回調函數,每次在圖像上單擊鼠標左鍵再擡起的過程,
【20180312】2018年03月12日(隨想)
post 而是 有一個 然而 clas OS you pos 一個 今天有一個熱點事件,在幾個群裏都有提及。 我以為是假的。沒想到是真的。果然還是太young了。 總結: 有的事,你認為是假的,它是真的。比如今天的焦點事件。 有的事,你認為一定是假的,偏偏是真
【PAT1135】Is It A Red-Black Tree(30)
earch represent uno nbsp pac ber key strong 節點 There is a kind of balanced binary search tree named red-black tree in the data structure.