錕斤拷是什麼?

鍒板簳浠?拷涔堟椂鍊欏紑 錕斤拷錕斤拷
錕斤拷錕剿達拷錕斤拷錕?16錕秸憋拷幕 錕斤拷錕斤拷錄冶錕斤拷錕斤拷?錕斤拷錕斤拷錕斤拷錕斤拷錕? 03錕斤拷15錕斤拷
錕斤拷[錕斤拷協十錕斤拷錕斤拷位錕斤拷錕絔協錕斤拷錕節撅拷錕街爸拷蟹錕斤拷錕斤拷錕斤拷錕? 03錕斤拷15錕斤拷
錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷錕狡伙拷錕斤拷羌牆錕斤拷錕斤拷錕餃拷錕絡錕斤拷 錕斤拷錕斤拷錕截伙拷 03錕斤拷14錕斤拷
錕斤拷錕斤拷要司錕斤拷錕斤拷錕酵籌拷台前錕斤拷通錕斤拷j錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷

例① From 看到的po:【最近從 Google 去貼吧都會跳到拷吧……】

例② ??????й?????

不說了……↑

每次看到這種東西都不由自主讀出來,然後就再也停不下來了。請問錕斤銬是什麼造成的?錕斤銬和銬斤錕形成模式一樣嗎?【【【認真的


哈哈哈,感覺LZ要百度一會gbk和utf8是什麼,你們都起開讓我來。

---------------- 寫在開始----------------
首先呢,假設LZ沒有計算機知識,我們來了解下什麼是編碼,編碼就是對計算機上的二進位信息的規則的識別,把二進位轉化為人可識別的字母漢子符號是decode過程,把人們了解的這些信息轉化為二進位存儲是encode過程。

計算機程序的存儲只有0和1,先不說漢子的表達,先說英文的表示方法

隨便在終端man 一下 ascii,截取了一小段,這就是一個二進位到可見字元的對應表。

舉個例子:我們看第二行,後面Oct是八進位表示,Dec是十進位,Hex是16進位表示,

「101 65 41 A」 這一欄 就是說 大寫字母「A」存儲在計算機的一個位元組里是 0x41,也就是二進位 "01000001",剛好佔據一個位元組(8bit),所以你在屏幕上看到的所有的字元「A」,其實在計算機內部都是用一個位元組存儲的,而內部的值是01000001。

上圖的編碼是ASCII (American Standard Code for Information Interchange),不是ASC2 ,不過這套編碼體系只解決了一些常用字元,控制字元,還有英文和數字等,最大表示的字元數也就只有一個位元組(8bit=256)那麼多 ,如果要表達中文或者這個星球上所有的其他語言以及表情符號,象形文字亂七八糟的,必須要擴充這個字符集,於是unicode系列就出來。

-------------- UNICODE系列 ----------------

Unicode 或者UCS(the Universal Character Set)是某一國際化組織(懶得百度)制定的可以容納世界(覆蓋人類已有文明)上所有文字和符號的字元編碼方案,要想做到這一點,那麼unicode的設計必須要足夠靈活。

Unicode用數字0-0x10FFFF來映射這些字元,最多可以容納1114112個字元,或者說有1114112個碼位。碼位是什麼?就是上面說的代表字元「A」的01000001,只不過這個只有一個位元組。可以想像這100多萬個數字應該足夠表達所有的字元了,吧。

為了表達更多的字元,只有8個bit是不夠的,於是便擴充了位元組數來表示更多的字元,那麼便出現了UCS-2和UCS-4,這兩者的區別就是,UCS-2用兩個位元組表示,而UCS-4用四個位元組表示,明顯後者比前者的表達能力要大,前者只有兩個位元組,兩個位元組是能表達多少?2^16= 65535,離unicode的目標0x10FFFF差距不少,但是有一些演算法可以滿足表達,暫且不說了,而UCS-4的4個位元組則完全沒問題了,好了這都不是重點。

重點是utf系列,unicode只是定義了一種映射表,也就是說65就是代表字母「A」,但是它怎麼存在計算機上自己定。也就是說還有一套轉換機制,叫UTF

---------------- UTF系列-----------------

UTF (Unicode Transformation Format)是吧unicode定義的映射表,存儲在計算機上的規則,比如 ascii的存儲方式就是 0x41,也就是存成01000001。

UTF分為 UTF-16 UTF-32 和UTF-8系列,後面這個數字的含義就是說用幾個位元組存儲了,USC-2對應的就是UTF-16,而USC-4對應的就是UTF-32,前者佔兩個位元組,表達能力弱一點,後者佔四個位元組表達能力強一點,但是無論前者還是後者,都是固定的用2個位元組或者四個位元組來表達一個字元,這顯然不能忍啊,如果我天天打英文,只用1個位元組就搞定了,你非要給我搞那麼多故事頭子幹嘛。

於是UTF-8就出現了,它在表達英文這種字元的時候和ascii碼一致(其實也並不完全一致,先不要在意),只需要8個位元組就夠了,當需要表達更多字元的時候,utf8會自動擴充,假如某個字元需要多於一個位元組表示,只看前兩位就知道了。

比如:

單位元組編碼的第一位元組為[00-7F]因為字母和常見字元只需要0~128個就可以表示,第一個bit只要不是1,那麼這個字元就是單位元組的。

雙位元組編碼的第一位元組為[C2-DF],當我讀下一個字元的時候,發現第一個位元組的開頭前兩個bit是11,那麼當前這個字元是雙位元組的。

三位元組編碼的第一位元組為[E0-EF]。當我讀下一個字元,發現第一個位元組的開頭三個bit是111,那麼這個字元就是三位元組的。

三位元組編碼的第一位元組為[F0-FF]。當我讀下一個字元,發現第一個位元組的開頭四個bit是1111,那麼這個字元就是四位元組的

怎麼樣,是不是沒聽懂!沒聽懂也不管了。

----------------GBK系列-----------------

中國人民爭強好勝,自己又定義了一套編碼,這個編碼是和Unicode兼容的,也就是說映射表是一樣的,比如漢子「水」的unicode編碼是 0x6C34,那麼它用utf8表示和用gbk表示,都是這個值,只是存儲在計算機上不太一樣。所以不了解unicode,只說gbk,utf8什麼的完全搞不清楚三者是什麼關係。

GBK編碼嚴格用了兩個位元組來表示字元,因為只給中國人用,只要表達漢子和字母就可以了,兩個位元組上面說能表達65536個字元,可見足夠了,可見中國標準委員會的眼光是多麼的淺,他們大概沒有遇到過編碼轉換問題,反正編碼轉換給現在互聯網公司帶來的坑太多了。(也不是說一點好處都沒有,utf8表達漢子要用3個位元組,2個位元組的gbk在存儲空間上省了一些)

在強調一遍,帶來的坑太多了,太多了,太多了!

GBK的編碼範圍是 0x8140-0xFEFE,詳細解刨一下

高位時0x81 ~ 0xFE 也就是 1000 0001 - 11111110
低位時0x40 ~ 0xFE 也就是 0100 0000 - 11111110
但不包括低位元組是0x7F的組合。

(低位元組是0x40-0x7E的組合是導致GBK是一個弱逼的主因,至於為什麼,可以觀察到, 高位元組的第一個bit是1,也就是說和asci的可見字元是不衝突的,而低位元組的開頭是0,那麼不難保證低位元組可能出現 01000001 這樣的字元,而這個字元恰好是ascii的 A,這不就衝突了么,衝突會導致有些用ascii作為分隔符來存儲gbk編碼數據的系統出現問題,好,打住)

有了上面的知識,下面我們來人肉編碼一下「水」這個字元的utf8編碼結構

「水」對應的unicode是 0x6C34 也就是 0110 (6) 1100(C) 0011(3) 0100(4) ,那麼咋的一看utf8要用3個位元組表示,第一個位元組是 1110 xxxx ,第二個位元組是 10 xxxxxx, 第三個位元組是 10 xxxxxx,我們把 0x6C34的值填充到這三個位元組的x里,得到 1110 0110, 10 110000,10 110100,這三個位元組就是 0xE6B0B4 ,也就是「水」的UTF8編碼了。

好,我們在順變人肉編碼一下水的GBK編碼,怎麼做呢?沒法做...

因為GBK的內碼不是連續的,而且和unicode標準沒有必然的關係,所以大部分程序在做轉換的時候都是依賴的轉換表。

--------------- 錕斤拷 ------------------

UNICODE的字元列表有一個特殊的字元,也就是0xFFFD,這個字元的wiki解釋是這樣的

  • U+FFFD ? replacement character used to replace an unknown or unrepresentable character

It is used to indicate problems when a system is not able to render a stream of data to a correct symbol. It is most commonly seen when a font does not contain a character, but is also seen when the data is invalid and does not match any character

它的用途是說,比如說android系統還沒有emoji表情的時候,你用你的iphone給android系統發送了一個emoji表情,那麼android的機器就傻了啊,這個該展示成什麼樣呢?於是這個字元就派上用場了,我把它展示為 ? 就行啦!

是的,這個字元的使用很依賴你當時所使用的程序,舉個很實際的例子,我在iphone上敲下了字元 "←←" ,這個符號"← ",的utf8編碼是 "0xe2 0x86 0x90" ,

對應的 unicode是什麼呢,我們換算一下 1110 0010 , 1000, 0110, 1001 0000 ,截取後半部分 , 是 0010 0001, 1001 0000 ,也就是 0x2190 ,這就是這個符號的unicode。

現在我把這個符號發送給一個根本不認識他的低端手機,比如就是安德猴好了,這個手機的編輯器看到這個unicode後不知道該渲染成什麼字元,因為它根本不認識,那麼它就把0x2190 替換為 0xFFFD,因為根據ucs標準,這個0xFFFD的符號是?,就是用來容錯的時候用的。

展示的時候存在手機上的是utf8編碼,那麼0xFFFD對應的utf8編碼是什麼呢?我們帶入三元組的utf8模版 就是 1110 1111 , 10 111111, 10 11 1101 ,那麼這用16進位表示就是 0xEF 0xBF 0xBD

好,下面才是真正的關鍵,"錕斤拷"是怎麼出現的呢,還有一步,這個編輯器轉換為 0xFFFD後給你看到了,同時存儲在手機上的utf8編碼是 0xEFBFBD ,然後這個使用安德猴的人手賤,他原封不動的把看到的信息轉發給另一個人,那個人使用的編輯器是用GBK解碼的,他並不知道這段字元原始的編碼格式是utf8,於是他按照gbk來解碼這三個字元,由於我在iphone上輸入的是兩個箭頭,那麼這個人接收到的數據應該是兩組 0xEFBFBD,也就是 0xEF 0xBF 0xBD 0xEF 0xBF 0xBD ,6個位元組,我們按照每兩個位元組,去查詢gbk編碼對應的漢子,就會發現剛好對應著這三個漢子

錕(0xEFBF)
斤(0xBDEF)
拷(0xBFBD)

於是,只有這第三個人看到的才是 錕斤拷。

所以很多時候這個問題有時候出現,有時候不出現,有時候有可能就是普通的亂碼,有些瀏覽器做的比較好也不會出現,這種情況必須要滿足上面列舉得三組條件才可以。

1. 大於一個稀有的字元 ,至少倆,不然無法配對
2. 某一編輯器或軟體識別不了,並且很有節操的給你替換成了0xFFFD展示
3. 展示後的文本又無節操(有可能這個人就是你)的直接傳遞給了另一個編輯器,而那個編輯器必須是GBK編碼的

以上。


遠古兵器。

傳說中的錕斤拷應該是手持兵器,很可能雙手持。

此物威力不可小覷,後人也有見過此物真身,但以其破壞力推測大概只是一些普通後代。

據說使用者通常心決簡潔,如你所料:燙燙燙。

手持兩把錕斤拷,口中疾呼燙燙燙。


Unicode和老編碼體系的轉化過程中,肯定有一些字,用Unicode是沒法表示的,Unicode官方用了一個佔位符來表示這些文字,這就是:U+FFFD REPLACEMENT CHARACTER。
那麼U+FFFD的UTF-8編碼出來,恰好是 "xefxbfxbd"。如果這個"xefxbfxbd",重複多次,例如 "xefxbfxbdxefxbfxbd",然後放到GBK/CP936/GB2312/GB18030的環境中顯示的話,一個漢字2個位元組,最終的結果就是:錕斤拷——錕(0xEFBF),斤(0xBDEF),拷(0xBFBD)

百度的,匿名了


是我的星座


gbk編碼傳過去,utf8的伺服器不認得,給你返回了容錯字元,又被gbk翻譯回了漢字。。


google給的鏈接是用gbk編碼的
baidu不知什麼時候改成utf-8了。gbk的字元在解碼成utf-8時候出了錯。
哎呀你去問飯否上問保證有百度的人把來龍去脈解釋清楚


燙燙燙燙燙燙燙燙燙


啊啊啊我的頁面是錕斤拷女座 我還一臉懵逼我是處女座啊,怎麼是錕斤拷女座


百度曾經出現過一次「錕斤拷」事件,被攻擊了,頁面文字基本全變成了這仨字。如果你翻翻也許還找得到一些截圖。當年也有過相關科普。
我不太清楚技術細節,只知道內碼識別的錯誤,導致這種不正常的顯示結果。


推薦閱讀:

在未來,記者、新聞編輯這類職業是否會消失?
國外常用的論文檢索網站有哪些?
在東京、大阪等日本大城市生活需要什麼必不可少的 App?
你最想給知乎哪些建議?
你厭煩豆瓣了嗎?

TAG:互聯網 | 字元編碼 | 字符集 |