在計算機中,所有的資料在儲存和運算時都要使用二進位制數表示(因為計算機用高電平和低電平分別表示1和0),例如,像a、b、c、d這樣的52個字母(包括大寫)、以及0、1等數字還有一些常用的符號(例如*、#、@等)在計算機中儲存時也要使用二進位制數來表示,而具體用哪些二進位制數字表示哪個符號,當然每個人都可以約定自己的一套(這就叫編碼),而大家如果要想互相通訊而不造成混亂,那麼大家就必須使用相同的編碼規則。
位元組是怎麼分組的,如8 bits或16 bits一組,這也被稱作編碼單元。
編碼單元和字元之間的對映關係。例如,在ascii碼中,十進位制65對映到字母a上
標準ascii 碼也叫基礎ascii碼,使用7 位二進位制數(剩下的1位二進位制為0)來表示所有的大寫和小寫字母,數字0 到9、標點符號, 以及在美式英語中使用的特殊控制字元。
如果你是乙個生活在2023年的程式設計師,卻不了解字元、字符集、編碼和unicode這些基礎知識。那你可要小心了,要是被我抓到你,我會讓你在潛水艇裡剝六個月洋蔥來懲罰你。
這個**的恐嚇是joel spolsky在十年前首次發出的。不幸的是,很多人認為他只是在開玩笑,因此,現在仍有許多人不能完全理解unicode,以及unicode、utf-8、utf-16之間的區別。這就是我寫這篇文章的原因。
最終,美國人意識到他們應該提出一種標準方案來展示世界上所有語言中的所有字元,以便緩解程式設計師的痛苦和避免字元編碼引發的第三次世界大戰。出於這個目的,unicode誕生了。
unicode背後的想法非常簡單,然而卻被普遍的誤解了。unicode就像乙個**本,標記著字元和數字之間的對映關係。joel稱之為「神奇數字」,因為它們可能是隨機指定的,而且不會給出任何解釋。官方術語是碼位(code point),總是用u+開頭。理論上每種語言中的每種字元都被unicode協會指定了乙個神奇數字。例如希伯來文中的第乙個字母א,是u+2135,字母a是u+0061。
unicode並不涉及字元是怎麼在位元組中表示的,它僅僅指定了字元對應的數字,僅此而已。
關於unicode的其它誤解包括:unicode支援的字元上限是65536個,unicode字元必須佔兩個位元組。告訴你這些的人應該去換換腦子了。
記住,unicode只是乙個用來對映字元和數字的標準。它對支援字元的數量沒有限制,也不要求字元必須佔兩個、三個或者其它任意數量的位元組。
unicode字元是怎樣被編碼成記憶體中的位元組這是另外的話題,它是被utf(unicode transformation formats)定義的。
這裡就有兩個嚴重的問題,第乙個問題是,如何才能區別 unicode 和 ascii ?計算機怎麼知道三個位元組表示乙個符號,而不是分別表示三個符號呢?第二個問題是,我們已經知道,英文本母只用乙個位元組表示就夠了,如果 unicode 統一規定,每個符號用三個或四個位元組表示,那麼每個英文本母前都必然有二到三個位元組是0,這對於儲存來說是極大的浪費,文字檔案的大小會因此大出二三倍,這是無法接受的。
它們造成的結果是:
1)出現了 unicode 的多種儲存方式,也就是說有許多種不同的二進位制格式,可以用來表示 unicode。
2)unicode 在很長一段時間內無法推廣,直到網際網路的出現。
utf-8 是乙個非常驚豔的編碼方式,漂亮的實現了對 ascii 碼的向後相容,以保證 unicode 可以被大眾接受。
utf-8 是目前網際網路上使用最廣泛的一種 unicode 編碼方式,它的最大特點就是可變長。它可以使用 1 - 4 個位元組表示乙個字元,根據字元的不同變換長度。編碼規則如下:
對於單個位元組的字元,第一位設為 0,後面的 7 位對應這個字元的 unicode 碼點。因此,對於英文中的 0 - 127 號字元,與 ascii 碼完全相同。這意味著 ascii 碼那個年代的文件用 utf-8 編碼開啟完全沒有問題。
對於需要使用 n 個位元組來表示的字元(n > 1),第乙個位元組的前 n 位都設為 1,第 n + 1 位設為0,剩餘的 n - 1 個位元組的前兩位都設位 10,剩下的二進位制位則使用這個字元的 unicode 碼點來填充。
編碼規則如下:
根據上面編碼規則對照表,進行 utf-8 編碼和解碼就簡單多了。下面以漢字「漢」為利,具體說明如何進行 utf-8 編碼和解碼。
「漢」的 unicode 碼點是 0x6c49(110 1100 0100 1001),通過上面的對照表可以發現,0x0000 6c49 位於第三行的範圍,那麼得出其格式為 1110***x 10****** 10******。接著,從「漢」的二進位制數最後一位開始,從後向前依次填充對應格式中的 x,多出的 x 用 0 補上。這樣,就得到了「漢」的 utf-8 編碼為 11100110 10110001 10001001,轉換成十六進製制就是 0xe6 0xb7 0x89。
解碼的過程也十分簡單:如果乙個位元組的第一位是 0 ,則說明這個位元組對應乙個字元;如果乙個位元組的第一位1,那麼連續有多少個 1,就表示該字元占用多少個位元組。
(1)gb2312字符集
gb2312是漢字字符集和編碼的代號,中文全稱為「資訊交換用漢字編碼字符集」,由中華人民共和國國家標準總局發布,一九八一年五月一日實施。gb是「國標」 二字的漢語拼音縮寫。
(2)gb2312字符集 (character set) 只收錄簡化字漢字,以及一般常用字母和符號,主要通行於中國大陸地區和新加坡等地。
(3)gb2312 共收錄有 7445 個字元,其中簡化漢字 6763 個,字母和符號 682 個。
(4)gb2312 將所收錄的字元分為 94 個區,編號為 01 區至 94 區;每個區收錄 94 個字元,編號為 01 位至 94 位。gb2312 的每乙個字元都由與其唯一對應的區號和位號所確定。例如:漢字「啊」,編號為 16 區 01 位。
(5)gb2312 字符集的區位分布表:
區號 字數 字元類別
01 94 一般符號
02 72 順序號碼
03 94 拉丁字母
04 83 日文假名
05 86 katakana
06 48 希臘字母
07 66 俄文本母
08 63 漢語拼音符號
09 76 圖形符號
10-15 備用區
16-55 3755 一級漢字,以拼音為序
56-87 3008 二級漢字,以筆劃為序
88-94 備用區
舉例來說,「啊」字是gb2312之中的第乙個漢字,它的區位碼就是1601。位元組編碼,通常採用euc儲存方法,以便相容於ascii。每個漢字及符號以兩個位元組來表示 。第乙個位元組稱為「高位位元組」,第二個位元組稱為「低位位元組」。 「高位位元組」使用了0xa1-0xf7(把01-87區的區號加上0xa0),「低位位元組」使用了0xa1-0xfe(把01-94加上0xa0)。例如 「啊」字在大多數程式中,會以0xb0a1儲存(與區位碼對比:0xb0=0xa0+16,0xa1=0xa0+1)。
notepad++,可以設定檔案編碼
ultraedit,可以檢視檔案的16進製制位元組流
字符集和字符集編碼詳解
gb2312 gbk ascii asni unicode utf 8等等,這些字眼非常常見,同時帶來許多的問題。本文只是從理解的角度,說明以上內容的不同含義從而達到區分其用法的目的是夠了的。至於實現方式,可以查閱各自的詳細標準官方文件。先解釋乙個概念,什麼是字符集,嗯,不解釋了,我弄乙個吧 從今以...
字符集和編碼
什麼是字元?字元就是文字和符號的統稱,字符集就是多個字元的集合,字符集有很多種,常見的有ascii,gb2312,unicode字符集。什麼是編碼?計算機要準確的處理字符集中的文字,就需要對字元進行編碼。對unicode字符集編碼的叫做unicode編碼,對ascii字符集編碼叫做ascii編碼。a...
編碼和字符集
ascii unicode gb2312等都是字符集,用於定義編號指代的字元。utf 8,utf 16則是unicode的編碼格式。ascii ascii只有128個,能表示英文 數字 常用符號。gb2312 gb2312是中文特有的字符集,有2萬多個字元,前128個和ascii保持一致,因此能相容...