close

ASCII 的限制

ASCII 碼最大的缺點就是只能夠對應英文字母、數字、以及簡單的英文符號,沒有辦法處理歐洲諸國文字,至於亞洲諸國文字就更不用提了!在商用電腦乃至於個人電腦漸漸普及的時代,這些問題漸漸浮上檯面。

 

8 位元擴展字碼表

首先,人們開始把腦筋動到那多出來的位元上面。 ASCII 7 位元的字碼表系統,總共有 128 種排列組合;但是電腦的一個位元組卻有 8 位元,共有 256 種排列組合,扣掉 ASCII 所使用的 128 碼,還有另外 128 碼是空著的。因此,西歐各國便用這多出來的 128 碼塞入各自的字母與符號,把 ASCII 擴展成為各國自己定義的 8 位元字碼表,解決了西歐各國各自的字元編碼問題。

 

東亞文字的問題催生多字元編碼

對於西歐諸國而言,一些特殊字母 ( 指相對於英文而言 ) 、帶重音符號字母、特殊符號等等加一加,塞入 8 位元的字碼表算是綽綽有餘,然而對中、日、韓這些東亞國家而言就不是這麼幸運了!日、韓不提,光是中文就號稱有 5 萬多字,怎麼樣也沒有辦法塞入只有 256 種排列組合的 8 位元字碼表。

還記得從前一個位元組只有 6 個位元,因為文字的需要而擴展為 7 位元的事嗎?當然,我們這次也可以主張一個位元組只有 8 位元是不夠用的,應該要擴充為 32 個位元等等,只是無耐時空環境已不同。當時的數位電腦發展處於發育時期,每臺電腦甚至連架構都不同,不差編碼這一塊,並且電腦不管是數量還是應用領域都有限,可以經得起更改;但到了 1970 年代,電腦的應用領域已經擴展於各種商業用途, Apple II 的出現更帶領出家用電腦的市場,隨後 IBM PC 系統逐漸成為個人電腦的統一架構。這個時候如果東亞人拋出要擴展位元組的議題的話大概會被全世界打死吧!

藉由擴展位元組解決問題的方式已不可行,因此使用多個位元組來表達一筆資料的方式便成為解決各種大型資料問題的辦法 ( 不只應用在字元編碼 ) ,也使得一個位元組等於 8 個位元這個慣例變得更加不可動搖。

 

中文五大碼

其他各國各自的編碼就不提了,本此主題將重心放在與大家較為切身相關的中文五大碼編碼系統上。

相信說中文、用中文的大家多少都聽過「大五碼」的威名。五大碼是 1984 3 月,資訊工業策進會與臺灣 13 家廠商簽定「 16 位元個人電腦套裝軟體合作開發計畫」,合作進行「五大中文套裝軟體專案」所開發出來的五種中文套裝軟體使用的內碼表。因此這套內碼表被稱為「五大碼」,英文就叫「 BIG-5 」,翻譯回來又叫「大五碼」。後來這五大套裝軟體未能成功進入市場,但其內碼表卻在往後成為業界標準,五大碼及其變種在全盛時期曾流行於中華民國、香港、及新加坡各界。

五大碼相容 ASCII 字碼,並使用兩個位元組表達一個中文字。當一個位元組所表達的數字介於 A1( 十六進位 ) FE 之間時代表下一個位元組要和這個位元組一起使用,當前這個位元組的碼被稱為「首碼」,下一個位元組則被稱為「次碼」。其中首碼值域介於 81-FE ,次碼值域介於 40-7E A1-FE ,次碼之有效數字跳過在 ASCII 中屬於控制字元的部份,這樣當五大碼的文字資料在不支援五大碼的系統上顯示時頂多顯示字樣不正確,而不會因為被當成 ASCII 碼所解析的控制字元造成其他災害。

由於五大碼總共有上萬字碼,因此不能像 ASCII 那樣在這裡直接列出字碼表,下面看一下五大碼的字碼分佈圖:

 

1 :五大碼編碼分佈示意圖 [12]

 

全形與半形

由於一個中文字佔用兩個位元組,而一個英文字母僅佔用一個位元組,這在當時的文字處理軟體上產生了問題,文字處理軟體因此不能夠很快的算出某行某字在記憶體中的位置,亦需分神來分辨處理一個字元時應該處理兩個位元組或是一個位元組。一個解決方法於是因應而生,於是五大碼的部份碼位被用來表示英文字母及數字,如此一來大家通通都佔用兩個位元組,就沒有那麼多計算與排版的問題了!這些使用兩個位元組表達的字母與 ASCII 的字母在字面意義上是相同的,但所佔用的記憶體空間不同、佔用的版面不同、其字碼亦完全不同,前者有個名字叫「全形字」,如ABC012;而原來的 ASCII 字母則又被稱為「半形字」,如 ABC012

 

中文內碼的戰爭

其實中文字碼的產生並不是這麼的簡單而順遂,早在五大碼產生前,就有「國字整理小組」所編之「中文資訊交換碼 (CCCII) 」,朱邦復先生也曾提出足以容納五萬多中文字的編碼方式,但最後均因故未獲得各界廣泛採用。在五大碼被廣泛應用後,還有倚天中文推出的「倚天碼」、以及臺北市電腦公會推出的「公會碼」試圖取得部份中文市場,但最後仍不能撼動大眾習慣已久之五大碼系統。

CCCII 雖能收錄所有正異體中文字,但其採用 3 位元組的編碼系統,在當時的文字編排技術下會產生字元難對齊以及資料佔用空間大的問題,因而未受市場所喜愛。雖然 CCCII 未能取得大眾市場,但其廣泛收錄中文字集的特性使得這套編碼系統在 Unicode 普及以前一直被使用在圖書館書目檢索等資訊交換系統上。

五大軟體專案雖然以失敗告終,但其所產生的五大碼中文編碼卻隨著國喬中文系統及倚天中文系統先後在臺灣市場獲得成功而獲得廣泛大眾的使用。微軟在開發早期的 Windows 系統時曾欲購買朱邦復先生所編之中文編碼系統來打入中文市場,唯其收購價格過高而作罷。從 Windows 3.1 開始,微軟採用五大碼推出中文版 Windows 系統,隨著 Windows 3.x 受到使用者的廣大迴響,更加奠定五大碼在大眾市場上的影響力。也由於從 Windows 3.1 及其後的 Windows 95 開始內建支援中文,使用者不再需要額外的中文支援系統,因此也開啟了國喬、倚天等中文支援系統商逐漸式微的命運。

 

五大碼的缺失與困境

五大碼的一大缺點就是許多的次碼會在不支援或不能正確解析五大碼的軟體上發生衝突,例如著名的「許功蓋」問題。先聲明在前,並不是只有「許功蓋」這三字會發生問題,只是在所有會發生類似問題的中文字當中,這三字幾乎是最常出現的,因此這三字常常成為這類問題的代表字。下面先看一下這三字在五大碼中的編碼為何:

 

文字

編碼

B35C

A55C

BB5C

2 :「許功蓋」字碼對應表

 

可以看到,許功蓋三字的次碼皆為 5C ,而 5C ASCII 裡是反斜線「 \ 」。也就是說,在不能正確解析五大碼的程式裡 ( 比方說外國人做的軟體 ) ,「許」這個字就會拆成 B3 5C 兩個字。 B3 反正已經超出 ASCII 的範圍,頂多就是不能顯示;但是後面的 5C 是個反斜線,偏偏反斜線在很多程式語言裡是具有特殊用途的!因此在 C/C++ HTML PHP SQL 等用途上都會造成很多鬼打牆的問題,其他更詳盡的說明可以參閱「網管很忙」的部落格 [4]

然而五大碼還存在著另一個與一般使用者更加切身相關的大問題,那就是缺漏字的問題。用兩個位元組表示一個中文字,亦即使用 16 個位元組成字碼表,理論上 16 個位元可以有 65536 種排列組合。但是扣掉 ASCII 所佔用的碼位、其他為避免產生衝突而放棄的碼位、以及部份全形半形符號後,實際上僅能對應約 13050 個中文字,然而中文號稱有五萬字,怎麼會夠用呢?原來他們當時是這樣想的:中文雖號稱有成千上萬的文字,但是屬於一般人常用字的只有約五千,因此一萬多字的字碼空間是綽綽有餘了,剩下的字就當它們不存在吧!這個方法乍聽之下很有道理,差只差在沒有想到中國人常常喜歡取一些奇奇怪怪的名字,萬一不巧這些人又成為名人,就會讓原來的罕用字變成常用字。因此大家可以看到「游錫堃」變成「游錫方方土」、「王建煊」變成「王建火宣」等等令人捧腹大笑的例子。另外一個受災戶就是在化學上的應用,連化學領域常見的「酶」字都沒有收錄,更別提眾多化學元素裡被這些文字專家們視為「罕見」的字了!

然而當時那批專家也不是真的這麼不堪,大家可以再看一下五大碼的編碼分佈圖,會發現有兩大塊的碼位是空下來的,叫做「造字區」。他的用意就是當我們遇到未被收錄的罕用字時,可以使用造字軟體製做新的文字,並將該字註冊至造字區上的某個碼位,這樣我們的電腦就能認識並顯示這個字了。所以從前在戶政事務所常見有些人登記姓名時需要由戶政所人員「造字」的情事。然而每臺電腦未必都有對某個字進行造字行為,並且同一個造字區的號碼在不同電腦上不見得註冊的是同一個字,因此這個做法的最大缺點為只適用於被造字的那臺電腦,而不利於資料傳輸與交換。

從最初五大碼成為大家所喜愛的統一的中文字碼系統,由於造字區各行其事的緣故反而成為不統一的字碼系統,數十年來對中文數位資訊的發展產生了相當的阻礙。

 

五大碼的改善方案

五大碼最大的問題就是缺漏字問題,缺漏字雖可透過造字來改善 ( 非解決 ) ,但由於各方在造字方面各行其事,反而造成另外的問題。那麼如果我們能夠制定一個統一的造字區,就可以很大程度的彌補這個缺漏字的問題。可惜的是五大碼其實是業界所「公認」的標準,實際上並沒有專職機構負責維護,大家都想要別人使用自己的造字區字碼,在臺灣較為有名的方案就有「倚天 BIG-5 延伸」、「中國海字集」、「中華民國教育部造字檔」、以及「 Unicode 補完計畫」等等 ( 註: Unicode 補完計畫的名稱裡雖然有 Unicode 字樣,但和真正的 Unicode 沒什麼關係 ) 。這些方案都是透過在五大碼的造字區擴充字碼來解決某些方面的應用問題,然而根本的缺漏字以及統一字碼的問題自始至終從未完善的解決,中文數位資訊的發展就在這麼樣的混亂情況下渡過了數十年。

 

各國字碼表系統造成的亂象

由於 ASCII 不敷使用,因此各國都做了自己的字碼擴充而形成各自一套字碼表系統,中、日、韓等東亞國家更是發展出不同的多位元組字碼表系統。本來各玩各的也沒什麼問題,但隨著網際網路的快速發展,各國紛亂的字碼表系統對資訊交流所引發的問題便浮現出來。

也許有些人曾經有過這樣的經驗,歐美或大陸的朋友寄來的電子郵件不能正確顯示 ( 亂碼 ) ,此時要先猜測他是使用什麼語言寫的信,然後將信件顯示的編碼設定更改為正確的編碼,或是一個一個試用所有的編碼,直到找到看起來不是亂碼的編碼為止。這樣的情況在很多的老網頁也適用。這些問題的源頭就是字碼表的不確定造成,當我用中文五大碼寫了信或做了網頁,而對岸同胞、甚至是歐洲朋友看見這些文字自然的都是亂碼。這問題是因為他們的電腦使用了當地的字碼表來解析我的五大碼資訊而造成,解決的方法就是觀看者必須告訴電腦這些文字的正確編碼方式,這樣電腦才知道應該如何解譯這些資料。但是這種做法只有在我們清楚對方所採用的字碼表時比較有用,有些資料 ( 或網站 ) 我們甚至難以判斷寫作者的國籍而必須一一猜測各種字碼表,然而全世界的字碼表何其多?這樣實在是太沒有效率了!

 

面對紛亂字碼系統的因應對策與侷限

近代的網頁瀏覽器以及文字檢視器相較於從前已經強大不少,面對這種未知系統編碼的資料時,這些軟體會嘗試去分析這些資料的組成最有可能符合哪一種編碼系統的常用慣例,從而自動選定可能性最高的字碼表來做解析。但即使如此仍然免不了有時會出現判斷錯誤的情形,因此在面對少數無法被正確判讀的文字檔案或網頁時,使用者仍需自行判斷並手動選擇使用的字碼表。

然而這樣的做法除了加重程式軟體的負擔之外,仍無法解決字碼混用的問題。傳統字碼表系統因為一種語言一個字碼表的緣故,因此無法在同一份文件、網頁、或程式裡將各國的語言一起顯示出來。也就是說,我們沒有辦法製做混合了各國語言的文件,比方說某些中文的論文中提到一些俄文的專有名詞等等。

傳統字碼表系統在網際網路興盛的時代衍生了諸多的不便與限制,而這些問題一直都處於無解的狀態,直到一種新的大型字碼表系統誕生。

 

 

 

 

參考資料:

 

  1. 大五碼、倚天中文 – 小木偶的網頁

    http://home.educities.edu.tw/wanker742126/asm/ap10.html

  2. 國內中文字碼之發展 – 交大資科BBS

    http://libai.math.ncu.edu.tw/~shann/Chinese/bbs97.html

  3. 王安電腦的興衰Jserv's blog

    http://blog.linux.org.tw/~jserv/archives/001393.html

  4. 「許功蓋」的問題 – 網管很忙

    http://203.64.20.7/lifetype126/index.php?op=ViewArticle&articleId=15&blogId=1

  5. 中文標準交換碼全字庫

    http://www.cns11643.gov.tw/AIDB/welcome.do

  6. 淺釋Unicode – novus

    http://novus.pixnet.net/blog/post/30371481-%E6%B7%BA%E9%87%8B-unicode

  7. 談程式碼使用的字集 – novus

    http://novus.pixnet.net/blog/post/30382414

  8. 每個軟體開發者都絕對一定要會的Unicode及字元集必備知識 – 周思博

    http://local.joelonsoftware.com/mediawiki/index.php/The_Joel_on_Software_Translation_Project:%E8%90%AC%E5%9C%8B%E7%A2%BC

  9. Unicode是用幾個位元來進行編碼? – LSS實驗室Beta

    http://lsslab.blogspot.tw/2008/03/unicode.html

  10. 非常經典的UTF-8 – Gea-Suan Lin's BLOG

    http://blog.gslin.org/archives/2013/10/01/3670/%E9%9D%9E%E5%B8%B8%E7%B6%93%E5%85%B8%E7%9A%84-utf-8/

  11. UTF-8 Everywhere

    http://www.utf8everywhere.org/

  12. 認識中文字元碼 – 中研院計算中心 曾士熊

    http://idv.sinica.edu.tw/bear/charcodes/codeindex.htm

  13. Wikipedia

    http://zh.wikipedia.org/wiki/%E5%A4%A7%E4%BA%94%E7%A2%BC

    http://zh.wikipedia.org/wiki/Unicode

    http://zh.wikipedia.org/wiki/UTF-32

    http://zh.wikipedia.org/wiki/UTF-16

    http://zh.wikipedia.org/wiki/UTF-8

    http://zh.wikipedia.org/wiki/UTF-7

arrow
arrow

    夜行者 發表在 痞客邦 留言(2) 人氣()