国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

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

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

典型亂碼

亂碼、問號、方塊

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

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

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

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

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

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

BOM

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

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

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

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

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

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

錕斤拷

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

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

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

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

燙燙燙、屯屯屯

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

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

URL Encode和Base64

URL Encode

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

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

對于非ASCII字符,將它的每個字節(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請求等操作的時(shí)候需要注意編碼。瀏覽器會按照當(dāng)前頁面所使用的字符編碼對表單體提交進(jìn)行URL Encode,但使用JavaScript的encodeURIencodeURIComponent的時(shí)候則總是會使用UTF-8(參考MDN)。

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

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

Base64

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

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

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

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

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

尾聲

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

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

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

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Python2.7字符編碼詳解
js-url編碼解碼
JAVA中文字符編碼問題詳解 控制臺輸出,字符編碼格式轉(zhuǎn)換
小結(jié)Python的中文處理
使用python進(jìn)行URL編碼
從零學(xué)習(xí)安全測試,從XSS漏洞攻擊和防御開始
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服