今天咱們不談編程,來聊聊歷史(笑=-=)css
同窗們請先思考一個問題:咱們只有十支手指,那麼怎麼用這十支手指表示超過10的數呢?好比說23!html
...前端
在好久好久之前,在沒有文字的年代,老古人結繩計數,一個結表明一個數字!html5
...web
當年周幽王烽火戲諸侯,只是爲得美人一笑,咱們就來聊一聊周幽王是怎麼想的(=-=!),古時候通訊是最大的問題,打仗的時候經過烽火臺傳遞敵情。根據敵情的不一樣,有着不一樣的規定。如一道烽火表明500人如下,兩道表明500~1000,三道表明1000到5000.。。。依次類推。其實這就是進制的雛形,經過不一樣數位表明不一樣的權重,來表示更大的數據。編程
不扯這些了,迴歸正題,如今的計算機仍然很弱小,你覺得計算機能夠存儲成千上萬種的語言,你覺得計算機能夠儲存任何文件,例如圖片、視頻,你覺得計算機能夠作任何計算,其實不是這樣的,計算機要比咱們想象中弱小的多,就算他再表現的強大,表現的更加人性化,他也只能認識0和1,只能處理二進制數據,這是咱們站在如今的角度去思考前人處理問題的方式,如今咱們站在前人的角度來想。1945年美國賓夕法尼亞大學的兩位教授-莫奇利和埃克特設計和研製出了世界上第一臺計算機ENIAC(電子數字積分計算機)。如今咱們有了第一臺計算機,可是這個計算機只認識0和1,這就須要咱們找到一個方法讓計算機「認識」其餘數據,這就是編碼(英語:encode),經過編碼的方式將咱們須要計算機認識的數據轉換爲二進制,讓計算機處理後,再解碼(英語:decode)呈現給咱們,除了計算機設計工做人員,其餘人通常不須要關心計算機是如何編碼和解碼的。瀏覽器
聲明:如下關於編碼的介紹轉自:騰訊遊戲官方設計團隊服務器
8個晶體管的「通」或「斷」便可以表明一個字節,剛開始,計算機只在美國使用,全部的信息在計算機最底層都是以二進制(「0」或「1」兩種不一樣的狀態)的方式存儲,而8位的字節一共能夠組合出256(2的8次方)種狀態,即256個字符,這對於當時的美國已是足夠的了,他們嘗試把一些終端的動做、字母、數字和符號用8位(bit)來組合:網絡
自此,一共只用到了128種狀態,即128個字符,恰好佔用了一個字節中的後7位,共包括33個控制字符和95個可顯示字符,這一字符集被稱爲ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼),這一套字符集在1967年被正式公佈。編輯器
講到這裏,引出幾個基礎概念:
如今咱們來看咱們文章開頭提到的第一條電報的誕生,莫爾斯編碼中包含了大小寫英文字母和數字等符號。
而電報的原理是:
「點」對應於短的電脈衝信號,「劃」對應於長的電脈衝信號,這些信號傳到對方,接收機把短的電脈衝信號翻譯成「點」,把長的電脈衝信號轉換成「劃」,譯碼員根據這些點劃組合就能夠譯成英文字母,從而完成了通訊任務。
而對於計算機誕生以後,只不過是將摩斯電碼中的「點」和「劃」換成了以8位字節二進制流的方式表示,如數字1的二進制流是0011 0001,對應的十進制流是49,十六進制流是31。
雖然剛開始計算機只在美國使用,128個字符的確是足夠了,但隨着科技驚人的發展,歐洲國家也開始使用上計算機了。不過128個字符明顯不夠呀,好比法語中,字母上方有注音符號,因而,一些歐洲國家就決定,利用字節中閒置的最高位編入新的符號。好比,法語的é的二進制流爲1000 0010,這樣一來,這些歐洲國家的編碼體系,能夠表示最多256個字符了。 可是,這裏又出現了新的問題。不一樣的國家有不一樣的字母,所以,哪怕它們都使用256個符號的編碼方式,表明的字母卻不同。好比,1000 0010在法語編碼中表明瞭é,在希伯來語編碼中卻表明了字母Gimel (?),在俄語編碼中又會表明另外一個符號。可是無論怎樣,全部這些編碼方式中,0--127表示的符號是同樣的,不同的只是128--255的這一段。 EASCII(Extended ASCII,延伸美國標準信息交換碼)由此應運而生,EASCII碼比ASCII碼擴充出來的符號包括表格符號、計算符號、希臘字母和特殊的拉丁符號:
EASCII碼對於部分歐洲國家基本夠用了,但事後的不久,計算機便來到了中國,要知道漢字是世界上包含符號最多而且也是最難學的文字。 據不徹底統計,漢字共包含了古文、現代文字等近10萬個文字,就是咱們如今平常用的漢字也有幾千個,那麼對於只包含256個字符的EASCII碼也難以知足天朝的需求了。 因而⌈中國國家標準總局⌋(現已改名爲⌈國家標準化管理委員會⌋)在1981年,正式制訂了中華人民共和國國家標準簡體中文字符集,全稱《信息交換用漢字編碼字符集·基本集》,項目代號爲GB 2312 或 GB 2312-80(GB爲國標漢語拼音的首字母),此套字符集於當年的5月1日起正式實施。
要知道港澳臺同胞使用的是繁體字,而中國大陸制定的GB2312編碼並不包含繁體字,因而信息工業策進會在1984年與臺灣13家廠商簽訂「16位我的電腦套裝軟件合做開發(BIG-5)計劃」,並開始編寫並推出BIG5標準。 以後推出的倚天中文系統則基於BIG5碼,並在臺灣地區取得了巨大的成功。在BIG5誕生後,大部分的電腦軟件都使用了Big5碼,BIG5對於以臺灣爲核心的亞洲繁體漢字圈產生了久遠的影響,以致於後來的window 繁體中文版系統在臺灣地區也基於BIG5碼進行開發。
在計算機進入中國大陸的相同時期,計算機也迅速發展進入了世界各個國家。 特別是對於亞洲國家而言,每一個國家都有本身的文字,因而每一個國家或地區都像中國大陸這樣去制定了本身的編碼標準,以便能在計算機上正確顯示本身國家的符號。 但帶來的結果就是國家之間誰也不懂別人的編碼,誰也不支持別人的編碼,連大陸和臺灣這樣只相隔了150海里,都使用了不一樣的編碼體系。 因而,世界相關組織意識到了這個問題,並開始嘗試制定統一的編碼標準,以便可以收納世界全部國家的文字符號。 在前期有兩個嘗試這一工做的組織:
國際標準化組織(ISO)及國際電工委員會(IEC)於1984年聯合成立了ISO/IEC小組,主要用於開發統一編碼項目; 而Xerox、Apple等軟件製造商則於1988年組成了統一碼聯盟,用於開發統一碼項目。 兩個組織都在編寫統一字符集,但後來他們發現各自在作相同的工做,同時世界上也不須要兩個不兼容的字符集,因而兩個組織就此合併了雙方的工做成果,併爲創立一個單一編碼表而協同工做。
1991年,兩個組織共同的工做成果Unicode 1.0正式發佈,不過Unicode 1.0並不包含CJK字符(即中日韓)。
|
ISO/IEC小組在1984年成立後的第三年(即1987年)開始啓動ISO 8859標準的編寫,ISO 8859是一系列8位字符集的標準,主要爲世界各地的不一樣語言(除CJK)而單獨編寫的字符集,一共定義了15個字符集:
其中ISO/IEC 8859-1至ISO/IEC 8859-4四個項目早在1982年就已經編寫出來,只不過是由ANSI與ECMA合做完成,並於1985年正式公佈,ISO/IEC小組成立後,這一成果被其收錄,並更名爲ISO/IEC 8859 前四個項目。 你們其實發現以上15個字符集中並無代號爲「ISO/IEC 8859 -12」的字符集,聽說-12號原本是預留給印度天城體梵文的,但後來卻擱置了(阿三有了本身的編碼-ISCII)。因爲英語沒有任何重音字母,故可以使用以上十五個字符集中的任何一個來表示。
1993年,ISO/IEC 10646標準第一次發表,ISO/IEC 10646是ISO 646的擴展,定義了1個31位的字符集。ISO 10646標準中定義的字符集爲UCS,UCS是Universal Character Set的縮寫,中文譯做通用字符集。
最初的ISO 10646-1:1993的編碼標準,即Unicode 1.1,收錄中國大陸、臺灣、日本及韓國通用字符集的漢字共計20,902個,固然每一個版本的Unicode標準的字符集所包含的字符數不盡相同,UCS包含了已知語言的全部字符,除了拉丁語、希臘語、斯拉夫語、希伯來語、阿拉伯語、亞美尼亞語、格魯吉亞語,還包括中文、日文、韓文這樣的方塊文字,此外還包括了大量的圖形、印刷、數學、科學符號。 UCS給每一個字符分配一個惟一的代碼,而且賦予了一個正式的名字,一般在表示一個Unicode值的十六進制數的前面加上「U+」,例如「U+0041」表明字符「A」。
UCS僅僅是一個超大的字符集,關於UCS制定的編碼方案有兩種:UCS-2和UCS-4,Unicode默認以UCS-2編碼。 顧名思義,UCS-2就是用兩個字節編碼,UCS-4就是用4個字節(實際上只用了31位,最高位必須爲0)編碼。那麼UCS-2其實能夠容納的字符數爲65536(2的16次方),而UCS-4能夠容納的字符數爲2147483648(2的31次方)。其實對於UCS-2已是徹底夠用了,基本能夠包含世界全部國家的經常使用文字,若是須要考慮一些偏僻字,那麼UCS-4則絕對能夠知足了,21億個字符哪怕是整個宇宙也夠用了吧!
Unicode 誕生,隨之而來的計算機網絡也發展了起來,Unicode 如何在網絡上傳輸也是一個必須考慮的問題,因而在1992年,面向網絡傳輸的UTF標準出現了。 UTF是Unicode Transformation Format的縮寫,中文譯做Unicode轉換格式。其實咱們從如今能夠把Unicode看做是一個標準或組織,而UCS就是一個字符集,那麼UCS在網絡中的傳輸標準就是UTF了。 前面提到了UCS的編碼實現方式爲UCS-2和UCS-4,即要麼是每一個字符爲2個字節,要麼是4個字節。若是一個僅包含基本7位ASCII字符的Unicode文件,每一個字符都使用2字節的原Unicode編碼傳輸,其第一字節的8位始終爲0,這就形成了比較大的浪費。可是,聰明的人們發明了UTF-8,UTF-8採用可變字節編碼,這樣能夠大大節省帶寬,並增長網絡傳輸效率。
使用1~4個字節爲每一個UCS中的字符編碼:
UCS-2的父集,使用2個或4個字節來爲每一個UCS中的字符編碼:
等同於UCS-4,對於全部字符都使用四個字節來編碼
前面提到了Unicode的迅速發展,至1993年時,包含CJK的Unicode 1.1已經發布了,天朝的ZF也意識到了須要一個更大的字符集來走向世界,因而在同一年,中國大陸制定了幾乎等同於Unicode1.1的GB13000.1-93國家編碼標準(簡稱GB13000)。是的,你沒聽錯,中華人民共和國信息產業部把Unicode裏的全部東東拿過來,而後本身從新修訂發佈了下,改成了國家標準GB13000。此標準等同於 ISO/IEC 10646.1:1993和Unicode 1.1。
1995年,在GB13000誕生後不久,中國教育科研網(NCFC)與美國NCFnet直接聯網,這一天是中國被國際認可爲開始有網際網路的時間。此後網絡正式開始在中國大陸接通,我的計算機開始在中國流行,雖然當時只是高富帥才消費得起的產品。中國是一個十幾億人口的大國,微軟意識到了中國是一個巨大的市場,當時的微軟也將本身的操做系統市場佈局進中國,進入中國隨之而來要解決的就是系統的編碼兼容問題。 以前的國家編碼標準GB 2312,基本知足了漢字的計算機處理須要,它所收錄的漢字已經覆蓋中國大陸99.75%的使用頻率。但對於人名、古漢語等方面出現的罕用字和繁體字,GB 2312不能處理,所以微軟利用了GB2312中未使用的編碼空間,收錄了GB13000中的全部字符制定了漢字內碼擴展規範GBK(K爲漢語拼音 Kuo Zhan中「擴」字的首字母)。因此這一關係實際上是大陸把Unicode1.1借鑑過來更名爲了GB13000,而微軟則利用GB2312中未使用的編碼空間收錄GB13000制定了GBK。因此GBK是向下徹底兼容GB2312的。
共收錄21886個字符, 其中漢字21003個, 字符883個
GBK只不過是把GB2312中未使用的空間,編碼了其餘字符,因此GBK一樣是用兩個字節爲每一個字符進行編碼。
微軟到了99年先後,說GBK已經落伍了,如今流行UTF-8標準,準備全盤轉換成UTF-8,但中國ZF不是吃素的,編寫並強制推出了GB18030標準。GB18030的誕生還有一個緣由是GBK只包含了大部分的漢字和繁體字等,咱們的少數民族兄弟根本木有考慮!中國有56個民族,其中有12個民族有本身的文字,那怎麼辦呢?在2000年,電子工業標準化研究所起草了GB18030標準,項目代號「GB 18030-2000」,全稱《信息技術-信息交換用漢字編碼字符集-基本集的擴充》。此標準推出後,在中國大陸以後的所售產品必須強制支持GB18030標準,否則不得賣!(這招挺狠的 - -#)
GB18030收錄了GBK中的全部字符,並將Unicode中其餘中文字符(少數民族文字、偏僻字)也一併收錄進來從新編碼。其中GB 18030-2000共收錄27533個漢字,而GB 18030-2005共包含70244個漢字。
採用多字節編碼,每一個字符由1或2或4個字節進行編碼
前面咱們穿越回過去對字符編碼作了下了解,那麼這些字符編碼跟咱們到底有啥關係?
當咱們打開編輯器coding時,按下ctrl+s的那一刻,其實等因而將本身的工做成果存儲進了計算機,而這裏最關鍵的是咱們以什麼字符編碼來進行存儲,咱們以intellij編輯器爲例:
咱們在編寫此文檔時,是以UTF-8編碼方式進行coding,當咱們按下ctrl+s時,則此文檔以utf-8編碼方式存儲進了計算機(右下角的UTF-8),而head區域中的<meat charset="utf-8">的做用則是告訴瀏覽器此文檔以utf-8編碼方式編碼。 咱們此時用Hex編輯器打開這個文件,來看看他的二進制流:
其中紅框標註出的即爲「小海」兩個中文字的二進制流,第一個爲"11100101 10110000 10001111"轉化爲十六進制則爲「E5B08F」,第二個爲「10110101 10110111 00001101」轉化爲十六進制爲「E6B5B7」,而當咱們去查詢UTF-8的碼錶時發現「E5B08F」對應的字符爲「小」,「E6B5B7」對應的字符則爲「海」,至此當咱們用瀏覽器進行預覽頁面時,因爲瀏覽器一樣以UTF-8方式對此頁面進行解碼,「小海」兩個字則能夠被正確的顯示出來。
作過前端的基本都遇到過亂碼問題吧?好吧,下面就帶你們來揭開這一神祕的面紗。
亂了有木有!竟然變成了「C??」,木有道理呀!我在用notepad編輯文件時採用的是gbk編碼,而頭部申明的也是gbk,自己notepad打開也是正常,但用intellij打開卻亂了!
罪魁禍首:編輯器默認編碼。每一個編輯器都會有默認編碼,若是沒有爲一個項目單獨設置過默認編碼,打開一個單獨的文件,編輯器每每以本身的默認編碼去解碼這個文件,如上圖,咱們的inellij編輯器的默認是UTF-8解碼,而文件是GBK編碼方式,那麼打開確定就是亂的拉。
因此編輯器也是一個因素,DW則能夠智能判斷文件的編碼方式,上述文件用DW打開並不會亂碼,而intellij可能對中文的支持並非很好,因此還不能智能判斷中文編碼,默認以UTF-8解碼(固然默認編碼本身是能夠修改的)。
不少讀者可能還有一個疑問,爲啥亂碼出來的是「C??」? 其實原理已在上面的基本原理中作過介紹,即編輯器ctrl+s存進計算機時是GBK,但嘗試用utf-8來解析,對應的utf-8中的碼錶中卻找到了「C??」,感興趣的同窗能夠本身研究下。
而後用瀏覽器打開後,就是這樣了:
亂了有木有!這個其實和編輯器打開一個文件亂碼的原理是一致的:即編輯器編碼時所採用的字符編碼和解碼時所採用的字符編碼不一致。上述栗子,咱們在coding時採用的是GBK編碼,但頭部卻告訴瀏覽器這個文檔是UTF-8編碼,那麼瀏覽器在用UTF-8解碼時就會出現了亂碼。
咱們在coding時須要告訴瀏覽器本身的文件採用了什麼字符編碼,下面列出一些常見的方法:
<meta charset="gb2312"> //html5
<meta http-equiv="Content-Type" content="text/html; charset=gb2312"> //html4 xhtml
<script src="http://ossweb-img.qq.com/images/js/foot.js" charset="gb2312"></script>
<link href="http://gameweb-img.qq.com/css/common.css" rel="stylesheet" charset="gb2312" >
咱們能夠在head區域的meta元素中爲整個頁面申明編碼方式,也能夠爲單獨的外鏈文件申明編碼方式(link/script等元素)。問題是若是頁面頭部和外鏈文件中只有部分申明或者所有申明,那麼對應的究竟是以什麼方式解碼呢?這裏就有一個優先級的問題,具體的斷定關係以下:
經過上述斷定,咱們其實能夠發現,一個頁面中優先級最高的實際上是服務端的編碼設置,若是一旦服務端設置了編碼A,那麼頁面即以A來解析。 目前Google採用的是這一作法,這樣的傳輸效率會更高,不須要在頭部額外再單獨申明編碼,但這樣其實也有必定的風險,除了須要有一個嚴謹的編碼規範,還須要確保服務器上的頁面都保持同一編碼,一旦不一致就會形成亂碼,因此目前這一方案在國內用的並很少。 其餘的,若是外鏈資源設置了編碼C,那麼即以C來解析,不管服務端和頭部是否申明編碼。 但必需要提醒你們的是:申明的編碼只是告訴瀏覽器相關的內容是以什麼方案去解碼,並非這一部份內容就採用了這個編碼。因此你們在coding時的編碼必定要確保和你申明的保持統一,否則就會出現亂碼的問題。
BOM是byte-order mark的縮寫,爲Unicode標準爲了用來區分一個文件是UTF-8仍是UTF-16或UTF-32編碼方式的記號,又稱字節序。
UTF-8以單字節爲編碼單元,並無字節序的問題,而UTF-16以兩個字節爲編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每一個編碼單元的字節序。例如「奎」的Unicode編碼是594E,「乙」的Unicode編碼是4E59。若是咱們收到UTF-16字節流「594E」,那麼這是「奎」仍是「乙」?這是UTF-16文件開頭的BOM就有做用了。
採用Unicode編碼方式的文件若是開頭出現了「FEFF」,「FEFF」在UCS中是不存在的字符,也叫作「ZERO WIDTH NO-BREAK SPACE」,那麼就代表這個文件的字節流是Big-Endian(高字節在前)的;若是收到「FFFE」,就代表字節流是Little-Endian(低字節在前)。
在UTF-8文件中放置BOM主要是微軟的習慣,BOM實際上是爲UTF-16和UTF-32準備的,微軟在UTF-8使用BOM是由於這樣能夠把UTF-8和ASCII等編碼明確區分開,但這樣的文件在Window之外的其餘操做系統裏會帶來問題。
咱們以Window下的文本文件爲例:
在保存時能夠選擇ANSI、Unicode、Unicode big endian和UTF-8四種編碼方式。
目前UTF-16一般用於系統文件的編碼,而UTF-32因爲對每一個字符都採用四個字節編碼,因此如今互聯網中大部分都採用UTF-8來進行編碼傳輸。
(左圖:中國地區ALEXA排名前20的站點所採用的編碼佔比) (右圖:騰訊互娛全部業務所採用的編碼佔比)
左圖代表GB23十二、GBK與UTF-8編碼三分天下,而右圖顯示騰訊互娛的業務大多數採用了GB2312,零星的採用了其餘編碼。總的就是不一樣的字符編碼方案基本都存在了,而這也與各公司業務的歷史緣由也有必定的關係。 當咱們在項目的最初期時採用了一種非Unicode編碼方案時,隨着業務的壯大,積累的頁面愈來愈多,到後期想去改爲Unicode編碼方案,就會擔憂出錯的問題,因此如今大多數公司都採用了延用初期編碼的方式,如淘寶,騰訊互娛等,以及四大門戶。
但是,某一天了,咱們的網站用戶港澳臺用戶也變多了,咱們須要支持繁體怎麼辦?
某一天,咱們的業務拓展到東南亞了,咱們須要咱們的網站也能支持那些國家的語言怎麼辦?
現在,國內大多數公司採用的方案是,爲相應的環境單獨作一套編碼文件,如 http://big5.china.com.cn/ ,又如 http://big5.qidian.com。
再好比,哪一天了,咱們的網站須要支持少數民族的語言怎麼辦?
難道像某某企業這樣切成圖麼?
嗯,這一切都只是暫時的方案,但人一旦變得懶起來,就不肯意去改變一些東西,就好比UTF-8。
一切就等着咱們敞開胸懷去擁抱,而不是沉浸在過去的喜悅中。最終的編碼方案決定權在咱們本身手裏,改變,只是時間的問題。