在這裡我簡單的談一下前端HTML與javascript日常工作中常碰到的編碼問題。
在電腦中,我們儲存的資訊都是用二進位碼錶示的。我們認識的、螢幕上顯示的英文、漢字等符號和儲存用的二進位代碼的互相轉換,就是編碼。
有兩個基本概念需要說明,charset 和 character encoding:
charset ,字元集,也就是某個符號和某個數字映射關係的一個表,也就是它決定了107 是koubei 的 ‘a',21475 是口碑的“口”,不同的表有不同的映射關係,如 ascii,gb2312,Unicode. 通過這個數字和字元的映射表,我們可以把一個二進位表示的數字轉換成某個字元。
chracter encoding ,編碼方式。例如,同是對於應“口”的 21475 這個數,我們是用 \u5k3e3 表示呢,還是用 %E5%8F%A3 來表示呢?這就是由 character encoding 來決定的。
對於 ‘koubei.com' 這樣的 字串來說,是美國人的常用字元,他們就制定了一個 叫做ASCII 的字元集,全稱是 american standard code of information interchange 美國標準資訊交換碼,用0–127這128個數字,(2的7次方,0×00-0×7f) 代表了123abc這樣的常用的128個字元。一共是 7 bits,再加上第一個是符號位,要用來去補碼反碼錶示負數什麼的,一共8 bits 構成一個 byte。當年美國人就是小氣了點,要是一開始就設計成一個 byte 是16 bits、32 bits,世界上會少很多問題,不過當時,估計他們覺得 8 bits 就夠了,可以表示128個不同的字元呢!
介於電腦這玩意兒是美國人搞出來的,所以他們自己省事,把自家用的符號都編碼好了,用的挺爽的。但當電腦開始國際化的時候,問題出來了,拿中國舉例吧,漢字就好幾萬,怎麼辦?
現有的 8 bits 一個 byte 的系統是基礎,不能破壞,不能去改到 16 bits之類的,否則改動太大了,只能走另一條路:用多個 ascii 的字元去表示一個其他字元,也就是 MBCS ( Multi-Byte Character System,多位元組字元系統)。
有了這個 MBCS 的概念,我們可以表示更多個字元了,比如我們用 2 個 ascii 字元,就有 16 bits, 理論上有 2 的 16 次方 65536 個字元。但這些編碼怎麼分配到字元上呢?比如口碑的”口”的 Unicode 編碼就是 21475,誰決定的呢?字元集,也就是剛剛介紹的charset。ascii就是最基礎的一個字元集,在此之上,我們有類似於 gb2312, big5這樣針對簡體中文和繁體中文的MBCS的字元集等等。終於有個叫 Unicode Consortium 的機構,決定做一個囊括所有字元在內的字元集(UCS, Universal Character Set)和對應編碼方式的標準,即 Unicode。從1991年開始,它發布了第一版 Unicode 國際標準,ISBN 0-321-18578-1 ,國際標準組織 ISO 也參與了這個的定製,ISO/IEC 10646 : the Universal Character Set。總之,Unicode 是個基本覆蓋了所有已經存在的地球上的符號的字元標準了,現在正在被越來越廣泛的使用,ECMA 標準也規定,javascript語言的內部字元使用 Unicode 標準(這意味著,javascript的變數名、函數名等是允許中文的!)。
對於身在中國的開發人員來說,可能碰到比較多的問題就是 gbk, gb2312, utf-8 之間轉換之類的問題了。嚴格的說這個說法不是很準確,gbk,gb2312是字元集 (charset),而 utf-8 是一種編碼方式 (character encoding) ,是 Unicode 標準中 UCS 字元集的一種編碼方式,因為使用 Unicode 字元集的網頁主要用UTF-8編碼,所以大家常常就把它們並列了,其實是不準確的。
有了 Unicode 後,至少人類文明沒有碰到外星人之前,這是一把萬能鑰匙了,都用它吧。而現在使用最廣泛 Unicode 的編碼方式就是 UTF-8 (8-bit UCS/Unicode Transformation Format) 了,它有幾個特別好的地方:
編碼 UCS 字元集,全世界通用
是一種變長編碼方式(variable-length character encoding),相容 ascii
第二點是個很大的優點,它使得以前使用純 ascii 編碼的系統相容,而且不會增加額外的儲存量(假設定長的編碼方式,規定每個字元由2個 bytes 組成,那麼這時候 ascii 字元佔用的儲存空間將增大一倍)。