乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      編碼歪傳在Windows上做開發(fā)的同學(xué),一定要選擇“使用UTF-8無BOM格式”保存

       看見就非常 2015-04-24

      我保證這是最后一篇了,而且這次的內(nèi)容絕對(duì)都是很具體的,具體得連每篇博客開頭例行的摘要我都不知道該寫什么了!

      典型亂碼

      亂碼、問號(hào)、方塊

      用文本編輯器打開一個(gè)文件,如果編碼不兼容,有時(shí)候會(huì)看到??????的東西,有時(shí)候會(huì)看到一團(tuán)亂七八糟的文字,通常我們就統(tǒng)稱亂碼了。怎么用編碼的知識(shí)來理解呢?

      前文中我們有說到實(shí)用的很多編碼方式都用的是變長(zhǎng)字節(jié)編碼,很多字節(jié)都要結(jié)合它的上下文去解釋才是對(duì)的。例如:用UTF-8的算法去解析GBK的文件,就很容易發(fā)些這么些種情況:

      1. 一個(gè)字節(jié)序列并不是合法的UTF-8字符,比如以11111110開頭的字節(jié)序列。
      2. 一個(gè)字節(jié)序列碰巧符合UTF-8規(guī)則。

      反過來看,用GBK的算法去解析UTF-8的文件其實(shí)也差不多,遇到第一種情況在顯示的時(shí)候可能就用問號(hào)代替,而遇到第二種情況就是出現(xiàn)一些風(fēng)馬牛不相及的雜亂文字。

      方塊其實(shí)和問號(hào)本質(zhì)上一樣的,但方塊在現(xiàn)代瀏覽器里還有個(gè)很常見的情況,就是一個(gè)字符的編號(hào)在字體當(dāng)中并沒有定義,于是在排版和渲染的適合“智能”地用一個(gè)方塊來表示它了??吹椒綁K可以結(jié)合上下文,如果上下文當(dāng)中的非英字符顯示正確的,那么方塊可能是一些特殊符號(hào),比如Emoji。

      在寫服務(wù)端程序的時(shí)候要小心處理“半個(gè)字符”的問題,例如我們?cè)谇凹?jí)對(duì)超長(zhǎng)的數(shù)據(jù)進(jìn)行截?cái)嗵幚?,剛好截?cái)嗟粢粋€(gè)變長(zhǎng)編碼的字節(jié)序列,就會(huì)出現(xiàn)“半個(gè)字符”。一般半個(gè)字符都是鐵定會(huì)亂碼,一些容錯(cuò)比較差的程序甚至?xí)欤热缫恍┳龅牟缓玫腜HP的C擴(kuò)展,嚴(yán)重的時(shí)候會(huì)出core。所以程序不懂編碼就別瞎截,甚至考慮到某些語言文字里的組合字符,就是知道編碼也別瞎截(真是細(xì)思恐極);

      BOM

      BOM就是Browser Object Model瀏覽器對(duì)象模型,不好意思拿錯(cuò)劇本了。

      BOM(Byte-Order Mark,字節(jié)序標(biāo)記)是Unicode碼點(diǎn)U+FEFF。它被定義來放在一個(gè)UTF-16文件的開頭,如果字節(jié)序列是FEFF那么這個(gè)文件就是大端序,如果字節(jié)序列是FFFE那么這個(gè)文件就是小端序。

      UTF-8本身是沒有字節(jié)序的問題的(因?yàn)樗且詥蝹€(gè)字節(jié)為最小單位),但是Windows里面很多編輯器(比如記事本)會(huì)多此一舉的在UTF-8文件開頭加入EF BB FF也就是U+FEFF的UTF-8編碼。

      如果你的PHP文件里面有一個(gè)這東西你就倒了大霉了,可能會(huì):

      • 什么也看不見,可能是PHP引擎根本處理不了這個(gè)源代碼。
      • 頁面展現(xiàn)錯(cuò)亂的情況,一般是因?yàn)樵?code><doctype>之前輸出的非空格內(nèi)容造成了瀏覽器選擇錯(cuò)誤的doctype。
      • 頁面上面有及格亂七八糟的字符,瀏覽器把它當(dāng)字符展示出來了。

      于是建議在Windows上做開發(fā)的同學(xué),一定要選擇“使用UTF-8無BOM格式”保存,所以用記事本寫代碼裝X就不好使了,用Notepad++的可以注意選一下,它支持的文件編碼格式挺豐富的,用一些比較先進(jìn)的跨平臺(tái)編輯器比如WebStorm、SublimeText它們都是沒BOM的。

      錕斤拷

      亂碼之所以叫亂碼,就是因?yàn)樗恰皝y”的。但是亂碼當(dāng)中最出名的就是“錕斤拷”,他出現(xiàn)次數(shù)太多了以至于看起來根本就沒那么“亂”。這就納了悶了,為什么全中國的網(wǎng)站亂碼里面都會(huì)有這個(gè)?

      原因是,在將一些國家語言編碼體系,比如GB、BIG-5、EUC-JP等,轉(zhuǎn)換為Unicode的過程中,多少有一些字符是不在Unicode中的(比如一些偏旁部首在Unicode里是后來才收錄的),甚至它本身在原來的編碼體系里面就是非法字符的情況。

      Unicode規(guī)定了U+FFFD當(dāng)作一個(gè)占位符用來表示這些字符,用UTF-8編碼它就是EF BF BD,連續(xù)多個(gè)這樣的字節(jié)序列出現(xiàn)就成了EF BF BD EF BF BD。如果是一個(gè)UTF-8的解析程序還好,而如果用一個(gè)GB的解析程序去打開,一個(gè)漢字2字節(jié),就成了“錕斤拷”。這里就是一個(gè)例子,用UTF-8編碼打開是問號(hào),用GBK編碼打開的話就會(huì)看到錕斤拷,用hexdump或者UltraEdit這類任何16進(jìn)制編輯器看的話就能看到里面都是EF BF BD

      要避免錕斤拷一個(gè)重要的點(diǎn)就是盡量減少程序當(dāng)中的編碼轉(zhuǎn)換。比如輸入是UTF-8,但是一個(gè)舊的模塊是GBK,把UTF-8轉(zhuǎn)成GBK交給舊的模塊處理,處理過程中舊模塊多多少少有些BUG的可能,再轉(zhuǎn)回來的時(shí)候就容易錕斤拷了。一個(gè)項(xiàng)目的源代碼在團(tuán)隊(duì)里面被不同的人(他們編輯器配置不盡相同)開來開去,存來存去,也很容易出現(xiàn)錕斤拷。

      燙燙燙、屯屯屯

      這個(gè)和編碼轉(zhuǎn)換其實(shí)沒啥關(guān)系,在VC的DEBUG模式下,會(huì)把未初始化的棧內(nèi)存全部填成0xCC,未初始化的堆內(nèi)存填成0xCD,這樣做是讓你一眼就能看出來你開了內(nèi)存沒初始化。

      而用GBK編碼的話,CC CC就是“燙”,CD CD就是“屯”。

      URL Encode和Base64

      URL Encode

      URL Encode又稱為“百分號(hào)編碼”它主要用來在URI里面將特殊字符進(jìn)行轉(zhuǎn)義,因?yàn)橄?code>/、&、=等等這類字符在URI里面本身是有功能性的。

      對(duì)于ASCII字符的編碼很簡(jiǎn)單就是用%后跟ASCII編碼的16進(jìn)制表示,例如/的ASCII char code是47,16進(jìn)制表示是2F,于是它的URL Encode結(jié)果就是%2F。

      對(duì)于非ASCII字符,將它的每個(gè)字節(jié)進(jìn)行相同規(guī)則的轉(zhuǎn)換,例如中文“編碼”的Unicode char code是U+7F16 7801,UTF-8編碼的字節(jié)序列是E7 BC 96 E7 A0 81,所以它按照UTF-8編碼的URL Encode結(jié)果就是%E7%BC%96%E7%A0%81。

      可以看出,URL Encode編碼非ASCII字符的時(shí)候,結(jié)果與使用的字符編碼有關(guān)。因此在頁面上提交表單、發(fā)起Ajax請(qǐng)求等操作的時(shí)候需要注意編碼。瀏覽器會(huì)按照當(dāng)前頁面所使用的字符編碼對(duì)表單體提交進(jìn)行URL Encode,但使用JavaScript的encodeURIencodeURIComponent的時(shí)候則總是會(huì)使用UTF-8(參考MDN)。

      表單提交的時(shí)候編碼是非常非常重要的,一旦錯(cuò)了服務(wù)端解開數(shù)據(jù)的時(shí)候就會(huì)跪。比如Github在它們的搜索表單里面放了一個(gè)<input name="utf8" type="hidden" value="?">,其中那個(gè)對(duì)鉤?是U+2713,UTF-8編碼是E2 9C 93,他們可以在服務(wù)端檢測(cè)這個(gè)參數(shù)的值對(duì)不對(duì)從而對(duì)URL里用的編碼進(jìn)行一個(gè)初步檢測(cè)。雖然我沒有看到他們使用其他編碼的情況,不過這樣也算是一個(gè)編碼協(xié)商和Check的手段吧。

      在JavaScript中使用escape也可以達(dá)到URL Encode的效果,但是它對(duì)于非ASCII字符使用了一種非標(biāo)準(zhǔn)的的實(shí)現(xiàn),例如“編碼”會(huì)被escape%u7F16%u7801這種%uxxxx奇怪的表示,W3C把這個(gè)函數(shù)廢棄了,身為一名前端還用是打臉的哦。

      Base64

      Base64是一種用可見字符表示二進(jìn)制數(shù)據(jù)的方法。它用了64個(gè)可見字符[A-Za-z0-9+/]。

      Base64的編碼程序非常簡(jiǎn)單,由于64=2^6,6和8的最小公倍數(shù)是24,也就是3byte,因此對(duì)輸入數(shù)據(jù)以3byte為一個(gè)單位,查表把它轉(zhuǎn)換成4個(gè)可見字符。

      如果輸入末尾不足3byte,那就補(bǔ)足,補(bǔ)1個(gè)byte就在輸出末尾添加一個(gè)=,補(bǔ)2個(gè)byte同理。

      Base64經(jīng)常用來在一些文本協(xié)議里面保存二進(jìn)制數(shù)據(jù),比如HTTP協(xié)議,或者電子郵件的附件啊什么的。同時(shí)因?yàn)樗妮敵鰧?duì)于人類而言不可讀,可以起到一些“混淆加密”的作用,事實(shí)上就有修改64個(gè)字符的排布來做一個(gè)變形Base64實(shí)現(xiàn)一個(gè)簡(jiǎn)單加密算法的例子。從密碼學(xué)的角度看它基本上沒什么強(qiáng)度可言,但是足夠簡(jiǎn)單,可以起到防君子不防小人的作用。

      由于一個(gè)字符只能編碼6bit,自身卻占了8bit,8/6=1.33,因此使用Base64來表示數(shù)據(jù)的時(shí)候會(huì)浪費(fèi)1/3的體積。對(duì)于在CSS里面用Base64的data-url方式表示圖片,用之前不妨簡(jiǎn)單估算一下,膨脹的體積和一個(gè)HTTP請(qǐng)求頭比起來會(huì)相差多少,說不定漲太多了已經(jīng)損失掉省一個(gè)請(qǐng)求的收益了。

      尾聲

      終于整個(gè)系列都要結(jié)束了,理論的也好,實(shí)用的也好,基本上我覺得該說的都說了,要是以后再遇到亂碼,一定會(huì)很快知道問題所在。

      最后還是要佩服并感謝一下ISO和Unicode聯(lián)盟,做了這么偉大的事情將全世界的語言文字統(tǒng)一收錄和編碼,而這當(dāng)中包括了那么多我們根本沒聽說過的奇怪的語言文字。正是因?yàn)樗麄兊呐Φ於嘶ヂ?lián)網(wǎng)是一個(gè)無國界的世界,每天我們都能通過它獲得來自任何地方任何語言的信息。

      哦,我上面說的不是某國的互聯(lián)網(wǎng)。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多