編程語言與計算機中的字符編碼

筆者學習計算機的時候,經常會遇到與字符編碼相關的問題,所以爲了方便查詢,就對常見字符編碼的來源,分類,內容等做了一下總結。筆者先簡單寫一部分,等後續遇到問題的時候再慢慢完善吧。
筆者在查詢相關資料的時候發現與字符編碼相關的內容太多了,所以就只列出主要框架,具體的細節就不深究了(想看細節的可以看看筆者貼出的參考文獻)。


概述

許多年以來,多數編程語言都使用一種名爲ASCII(American Standard Code for Information Interchange)的標準,在計算機內部表示字符,這種標準包括128個字符,足夠表示英語中經常出現的特殊字符。但如果去表示世界上所有語言中的字符和符號,就遠遠不夠啦。
所以人們逐漸轉向了Unicode標準。Unicode標準是一個字符編碼系統,支持數字化處理和所有語言的書面文本顯示。目前Unicode標準中的字符超過120000個,覆蓋了129中從古至今的語言和符號集合。
而Unicode標準可以通過各種內部字符編碼來實現。現在萬維網上用於實現Unicode標準最常使用的字符編碼是UTF-8。

歷史

ASCII標準是從電報代碼開始開發的。它的第一個商業用途是作爲一個七位 電傳貝爾數據業務推廣代碼。
關於ASCII標準的制訂工作始於1960年10月6日,美國標準協會(ASA)(現爲美國國家標準協會或ANSI)X3.2小組委員會的第一次會議。
該標準的第一版於1963年出版,於1967年進行了重大修訂,並經歷了1986年的最新更新。與早期的電報代碼相比,所提出的貝爾代碼和ASCII都被排序,以便更方便地對列表進行排序(即字母化),併爲除電傳打印機之外的設備增加功能。
ASCII碼錶
早於1972年的打印機手冊中的ASCII,圖來自ASCII的維基百科
最初的ASCII基於英文字母,將128個指定字符編碼爲7位整數,如上面的ASCII圖所示。其中95個編碼字符是可打印的:這些字符包括數字0到9,小寫字母a到z,大寫字母A到Z,以及標點符號。此外,原始的ASCII規範包括33個非打印控制代碼,這些代碼源自Teletype機器 ; 但是其中大部分已經過時,現在僅有一些常用,例如回車,換行和Tap。

ASCII標準最初是美國國家標準,供不同計算機在相互通信時用作共同遵守的西文字符編碼標準,它已被國際標準化組織(International Organizationfor Standardization,ISO)定爲國際標準,稱爲ISO 646標準,適用於所有拉丁文字字母。ISO / IEC 646是一組ISO標準的名稱,描述爲信息技術 - 用於信息交換的ISO 7位編碼字符集,至少自1964年以來與ASCII合作開發。第一版在1967年完成。

英語用 128 個字符來編碼完全是足夠的,但是用來表示其他語言,128 個字符是遠遠不夠的。於是,一些歐洲的國家就決定,將 ASCII 碼中閒置的最高位利用起來,這樣一來就能表示 256 個字符。但是,這裏又有了一個問題,那就是不同的國家的字符集可能不同,就算它們都能用 256 個字符表示全,但是同一個碼
點(也就是 8 位二進制數)表示的字符可能可能不同。例如,144 在阿拉伯人的 ASCII 碼中是 گ,而在俄羅斯的 ASCII 碼中是 ђ。

因此,ASCII 碼的問題在於儘管所有人都在 0 - 127 號字符上達成了一致,但對於 128 - 255 號字符上卻有很多種不同的解釋。與此同時,亞洲語言有更多的字符需要被存儲,一個字節已經不夠用了。於是,人們開始使用兩個字節來存儲字符。

各種各樣的編碼方式成了系統開發者的噩夢,因爲他們想把軟件賣到國外。於是,他們提出了一個“內碼錶”的概念,可以切換到相應語言的一個內碼錶,這樣才能顯示相應語言的字母。在這種情況下,如果使用多語種,那麼就需要頻繁的在內碼錶內進行切換。

最終,美國人意識到他們應該提出一種標準方案來展示世界上所有語言中的所有字符,出於這個目的,Unicode誕生了。

對於 Unicode 有一些誤解,它僅僅只是一個字符集,規定了符合對應的二進制代碼,至於這個二進制代碼如何存儲則沒有任何規定。它的想法很簡單,就是爲每個字符規定一個 用來表示該字符的數字,僅此而已。

Unicode標準於1990年開始研發,1994年正式公佈。隨着計算機工作能力的增強,Unicode也在面世以來的十多年裏得到普及。
Unicode 11.0版已發佈(2018年6月5日)。在Unicode聯盟網站上可以查看完整的11.0的核心規範。
Unicode定義了大到足以代表人類所有可讀字符的字符集。

ASCII

ASCII 碼使用指定的7 位或8 位二進制數組合來表示128 或256 種可能的字符。標準ASCII 碼也叫基礎ASCII碼,使用7 位二進制數(剩下的1位二進制爲0)來表示所有的大寫和小寫字母,數字0 到9、標點符號, 以及在美式英語中使用的特殊控制字符。其中:
0~31及127(共33個)是控制字符或通信專用字符(其餘爲可顯示字符),如控制符:LF(換行)、CR(回車)、FF(換頁)、DEL(刪除)、BS(退格)、BEL(響鈴)等;通信專用字符:SOH(文頭)、EOT(文尾)、ACK(確認)等;ASCII值爲8、9、10 和13 分別轉換爲退格、製表、換行和回車字符。它們並沒有特定的圖形顯示,但會依不同的應用程序,而對文本顯示有不同的影響。
32~126(共95個)是字符(32是空格),其中48~57爲0到9十個阿拉伯數字。
65~90爲26個大寫英文字母,97~122號爲26個小寫英文字母,其餘爲一些標點符號、運算符號等。
同時還要注意,在標準ASCII中,其最高位(b7)用作奇偶校驗位。所謂奇偶校驗,是指在代碼傳送過程中用來檢驗是否出現錯誤的一種方法,一般分奇校驗和偶校驗兩種。奇校驗規定:正確的代碼一個字節中1的個數必須是奇數,若非奇數,則在最高位b7添1;偶校驗規定:正確的代碼一個字節中1的個數必須是偶數,若非偶數,則在最高位b7添1。
後128個稱爲擴展ASCII碼。許多基於x86的系統都支持使用擴展(或“高”)ASCII。擴展ASCII 碼允許將每個字符的第8 位用於確定附加的128 個特殊符號字符、外來語字母和圖形符號。

Unicode

Unicode是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案,
最初的unicode編碼是固定長度的,16位,也就是2兩個字節代表一個字符,這樣一共可以表示65536個字符。顯然,這樣要表示各種語言中所有的字符是遠遠不夠的。Unicode4.0規範考慮到了這種情況,定義了一組附加字符編碼,附加字符編碼採用2個16位來表示,這樣最多可以定義1048576個附加字符,目前unicode4.0只定義了45960個附加字符。

Unicode只是一個編碼規範,目前已經實現並流行的unicode編碼只要有三種:UTF-8,UCS-2(是UTF-16的低配版)和UTF-16,三種unicode字符集之間可以按照規範進行轉換。此外UTF-32應該有部分應用了。

Unicode可容納的字符總數爲17*65536=1114112個,但目前實際應用到的只是其中的一小部分。請注意,這是個編碼方案(或者說編碼標準),它爲世界上目前已存在的所有文字和符號以及將來可能出現的字符都指定(或者說預留)了一個唯一的數字編碼,但它並不是具體的實施方式,也就是說Unicode中的數字編碼和電腦上的文字編碼是不能直接劃等號的,UTF-8、UTF-16和UTF-32纔是具體的實施方式,其中UTF-8用8位的倍數來表示一個字符,也就是說在UTF-8編碼格式中,一個字符可以是8位(一個字節)、16位(兩個字節)、24位(三個字節)、32位(四個字節),同理,UTF-16則可以是16位(兩個字節)、32位(四個字節),而UTF-32則所有字符都是32位(即四個字節)的。事實上,用三個字節表示一個字符的容量(16777216)已經遠遠超過Unicode標準中的最大容量(1114112)了。

引用

[1]ASCII,百度百科,https://baike.baidu.com/item/ASCII/309296
[2]Unicode,百度百科,https://baike.baidu.com/item/Unicode/750500
[3]徹底弄懂 Unicode 編碼,https://blog.whezh.com/encoded/
[4]ASCII,wikipedia,https://en.wikipedia.org/wiki/ASCII
[5]ISO / IEC 646,wikipedia,https://en.wikipedia.org/wiki/ISO/IEC_646
[6]UNICODE容納65536 個字符,怎麼裝得下9萬多漢字的?百度知道,https://zhidao.baidu.com/question/1707536489961769300.html
[7]Unicode字符集中最大允許有多少字符?目前已經定義了多少個字符? 百度知道,https://zhidao.baidu.com/question/483675784.html
[8]python編程導論第二版,John V.Guttag著,陳光欣譯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章