我保證這是最后一篇了,而且這次的內(nèi)容絕對都是很具體的,具體得連每篇博客開頭例行的摘要我都不知道該寫什么了! 典型亂碼亂碼、問號、方塊用文本編輯器打開一個文件,如果編碼不兼容,有時候會看到 前文中我們有說到實用的很多編碼方式都用的是變長字節(jié)編碼,很多字節(jié)都要結(jié)合它的上下文去解釋才是對的。例如:用UTF-8的算法去解析GBK的文件,就很容易發(fā)些這么些種情況:
反過來看,用GBK的算法去解析UTF-8的文件其實也差不多,遇到第一種情況在顯示的時候可能就用問號代替,而遇到第二種情況就是出現(xiàn)一些風(fēng)馬牛不相及的雜亂文字。 方塊其實和問號本質(zhì)上一樣的,但方塊在現(xiàn)代瀏覽器里還有個很常見的情況,就是一個字符的編號在字體當(dāng)中并沒有定義,于是在排版和渲染的適合“智能”地用一個方塊來表示它了??吹椒綁K可以結(jié)合上下文,如果上下文當(dāng)中的非英字符顯示正確的,那么方塊可能是一些特殊符號,比如Emoji。 在寫服務(wù)端程序的時候要小心處理“半個字符”的問題,例如我們在前級對超長的數(shù)據(jù)進行截斷處理,剛好截斷掉一個變長編碼的字節(jié)序列,就會出現(xiàn)“半個字符”。一般半個字符都是鐵定會亂碼,一些容錯比較差的程序甚至?xí)?,比如一些做的不好的PHP的C擴展,嚴重的時候會出core。所以程序不懂編碼就別瞎截,甚至考慮到某些語言文字里的組合字符,就是知道編碼也別瞎截(真是細思恐極); BOM
BOM(Byte-Order Mark,字節(jié)序標(biāo)記)是Unicode碼點 UTF-8本身是沒有字節(jié)序的問題的(因為它是以單個字節(jié)為最小單位),但是Windows里面很多編輯器(比如記事本)會多此一舉的在UTF-8文件開頭加入 如果你的PHP文件里面有一個這東西你就倒了大霉了,可能會:
于是建議在Windows上做開發(fā)的同學(xué),一定要選擇“使用UTF-8無BOM格式”保存, 錕斤拷亂碼之所以叫亂碼,就是因為它是“亂”的。但是亂碼當(dāng)中最出名的就是“錕斤拷”,他出現(xiàn)次數(shù)太多了以至于看起來根本就沒那么“亂”。這就納了悶了,為什么全中國的網(wǎng)站亂碼里面都會有這個? 原因是,在將一些國家語言編碼體系,比如GB、BIG-5、EUC-JP等,轉(zhuǎn)換為Unicode的過程中,多少有一些字符是不在Unicode中的(比如一些偏旁部首在Unicode里是后來才收錄的),甚至它本身在原來的編碼體系里面就是非法字符的情況。 Unicode規(guī)定了 要避免錕斤拷一個重要的點就是盡量減少程序當(dāng)中的編碼轉(zhuǎn)換。比如輸入是UTF-8,但是一個舊的模塊是GBK,把UTF-8轉(zhuǎn)成GBK交給舊的模塊處理,處理過程中舊模塊多多少少有些BUG的可能,再轉(zhuǎn)回來的時候就容易錕斤拷了。一個項目的源代碼在團隊里面被不同的人(他們編輯器配置不盡相同)開來開去,存來存去,也很容易出現(xiàn)錕斤拷。 燙燙燙、屯屯屯這個和編碼轉(zhuǎn)換其實沒啥關(guān)系,在VC的DEBUG模式下,會把未初始化的棧內(nèi)存全部填成 而用GBK編碼的話, URL Encode和Base64URL EncodeURL Encode又稱為“百分號編碼”它主要用來在URI里面將特殊字符進行轉(zhuǎn)義,因為像 對于ASCII字符的編碼很簡單就是用 對于非ASCII字符,將它的每個字節(jié)進行相同規(guī)則的轉(zhuǎn)換,例如中文“編碼”的Unicode char code是 可以看出,URL Encode編碼非ASCII字符的時候,結(jié)果與使用的字符編碼有關(guān)。因此在頁面上提交表單、發(fā)起Ajax請求等操作的時候需要注意編碼。瀏覽器會按照當(dāng)前頁面所使用的字符編碼對表單體提交進行URL Encode,但使用JavaScript的 表單提交的時候編碼是非常非常重要的,一旦錯了服務(wù)端解開數(shù)據(jù)的時候就會跪。比如Github在它們的搜索表單里面放了一個 在JavaScript中使用 Base64Base64是一種用可見字符表示二進制數(shù)據(jù)的方法。它用了64個可見字符 Base64的編碼程序非常簡單,由于64=2^6,6和8的最小公倍數(shù)是24,也就是3byte,因此對輸入數(shù)據(jù)以3byte為一個單位,查表把它轉(zhuǎn)換成4個可見字符。 如果輸入末尾不足3byte,那就補足,補1個byte就在輸出末尾添加一個 Base64經(jīng)常用來在一些文本協(xié)議里面保存二進制數(shù)據(jù),比如HTTP協(xié)議,或者電子郵件的附件啊什么的。同時因為它的輸出對于人類而言不可讀,可以起到一些“混淆加密”的作用,事實上就有修改64個字符的排布來做一個變形Base64實現(xiàn)一個簡單加密算法的例子。從密碼學(xué)的角度看它基本上沒什么強度可言,但是足夠簡單,可以起到防君子不防小人的作用。 由于一個字符只能編碼6bit,自身卻占了8bit,8/6=1.33,因此使用Base64來表示數(shù)據(jù)的時候會浪費1/3的體積。對于在CSS里面用Base64的data-url方式表示圖片,用之前不妨簡單估算一下,膨脹的體積和一個HTTP請求頭比起來會相差多少,說不定漲太多了已經(jīng)損失掉省一個請求的收益了。 尾聲終于整個系列都要結(jié)束了,理論的也好,實用的也好,基本上我覺得該說的都說了,要是以后再遇到亂碼,一定會很快知道問題所在。 最后還是要佩服并感謝一下ISO和Unicode聯(lián)盟,做了這么偉大的事情將全世界的語言文字統(tǒng)一收錄和編碼,而這當(dāng)中包括了那么多我們根本沒聽說過的奇怪的語言文字。正是因為他們的努力奠定了互聯(lián)網(wǎng)是一個無國界的世界,每天我們都能通過它獲得來自任何地方任何語言的信息。 哦,我上面說的不是某國的互聯(lián)網(wǎng)。 |
|