ASCII 、GB2312、GBK、UTF-8 編碼|0x7f-0xff____編碼

來源:互聯網
上載者:User
ASCII 、GB2312、GBK、UTF-8 編碼:

原文地址:http://hi.baidu.com/phpease/item/f450b5caec143014505058fc


變數命名規則:

1.  變數名區分大小寫(case-sensitive) 。

2.  必須字母或底線開頭。變數名可由 字母、數字、底線組成。  


看到這裡可能,很多人納悶了~。那為啥  $我是變數    這樣的中文也能做變數名呢。 在PHP裡,中文的確是可以做變數名的(能用是能用但千萬別項目上用....) 。 因為這裡的字母是指: a-z   A-Z  和  擴充ASCII 字元裡從 127 到 255  ,16進位表示為:0x7f-0xff   。 那意思就是ASCII字元裡從127到255 (0x7f-0xff) 涵括了中文。 的確是這樣的。下面就簡單的講下編碼。


ASCII 、GB2312、GBK、UTF-8  編碼:


ASCII :

ASCII 編碼裡包括了128個字元。用 十進位 0  到 127 來表示 。那就對了, 0 到 127 不就是 128個字元嗎。 每一個數字都代表一個字元。看ASCII 編碼錶




我們先看十進位(Dec) 這列,看到了嗎 。0對應於null(字串的末尾分隔字元\0) ,十進位數字  9 對應 的字元是 我們開發用得最多的 TAB鍵。 再看看 48 對應的字元是  0 。沒錯從  ASCII  48開始 到57 都表示數字  0到9 。  ASCII  97 到 122 表示 小寫字母 a 到 z 。   比如: 我們看到的字母 a  ,其實電腦並不認識啥 字母a , 她只認識  97。 她把a 轉成了 ASCII 97來進行儲存。下面用PHP 來玩玩 ASCII 。


來我們認識兩個函數:

ord  ----  Return ASCII value of character     返回 字元竄的 ASCII 值 。

chr  ----  Return a specific character     返回 ASCII 對應的 字元。

 

翠花上例子:

<?php echo(ord('a'));?>

//輸出   97  

沒錯吧,  小寫a的 ASCII 就是  97。   要把 ASCII 97  對應的字元列印出來:

<?php echo(chr(97));?>

//輸出 a 

恩。看完基本就明白了。  ASCII 編碼 裡麵包括了  大小寫字母   數字 和 一些常用的控制字元。 這樣在使用英語的國家基本就能使用了。電腦儲存的是ASCII 。 人看到的就是 ASCII 對應的字元。

 

GB2312 編碼:

世界上並不全是用英語作為語言的。比如我國用的是中文。小日本用的是 日語。 韓國用的是韓文。 這些語言和英語完全不是一回事。 你看ASCII 表上有中文對應的”數字“嗎。沒有吧。因為還有一份 GB2312編碼錶 ,和ASCII 編碼錶道理一樣。  連結: http://wenku.baidu.com/view/244e2d2ce2bd960590c677a6.html     大家開啟一看,哎呀~~。 是否有點亂亂,找不到頭緒,啥亂七八糟。 不過當明白原理,就容易看懂了。

 

在GB2312編碼裡面,一個字元我們需要用兩個位元組來進行儲存和表示。我們記得ASCII 編碼裡面 一個字元只需要一個位元組。所以以GB2312儲存資料比 ASCII 大一倍。 那麼GB2312 這兩個位元組,分別放啥數字 才能表示字母 a 呢。 我們知道 ASCII 編碼  a  就一個位元組表示,編碼97。 GB2312 編碼比 ASCII 複雜一點,


 在要看懂 GB2312編碼錶之前,首先我們要學習下”區位碼“。


區位碼概念:

GB2312對漢字和其他字元(字母,數字等)進行了“分區”。

       01-09區為特殊符號(數字呀、字母呀等)。

       16-55區為一級漢字,按拼音排序。

       56-87區為二級漢字,按部首/筆畫排序。


分區是啥。比如我是廣西的,你是河南的、他是廣東。 也就是說每個字元肯定存在於某個區裡。  這種表示方式叫做 “區位碼”。  區位碼 其實是   區號和位號(表示一個字元在這個哪個區裡的第幾列) 。 你想知道每個漢字的區位碼。簡單呀。給你個連結自己查去  http://www.jscj.com/index/gb2312.php       



我們以   “啊” 這個漢字來查它的區位碼。  以上圖所示   1601  是 “啊”這個漢字的區位碼。  區號是 16 ,  位號  01。     如果大家還記得,  16區 是 一級漢字哦。牛X呀。一級漢字是啥意思。 我估計是常用的漢字。~我也不知道,這個是國內專家定義的。  位號 是 01   ,位號其實就是說你在這個區裡排行老幾。  有了 x軸(區號)和y軸(位號) 那麼自然就又個交點,通過交點就能在 GB2312編碼錶上找到對應的漢字了。


如果你現在就去看 GB2312的編碼錶,我估計你還是看不懂,雖然說通過區位碼就能定位到GB2312編碼的字元了。但是GB2312編碼錶上並沒那麼單純。 還要繼續往下看。

 

上面我們說的是GB2312的  區位碼: 區號和位號。   前面我說過,一個GB2312的字元 是用兩個位元組來表示的:(高位位元組,低位位元組)。第一個位元組稱為“高位位元組” ,第二個位元組稱為“低位位元組”  ps:因為高的一般排左邊吧~  所以叫 高位位元組....    。

演算法如下: 一個GB2312的字元  ==  (0xA0 + 區號,0xA0 + 位號)。按照這個演算法,你再取看 GB2312編碼錶,你就看得如魚得水了。

 

0xA0 是啥意思呢。  為啥高位位元組 等於 區號 加上  0xA0 。  為啥低位位元組 等於 位號 加上 0xA0呢。這樣組合起來的兩個位元組就能表示一個 GB2312的字元。  沒錯,就是那麼簡單。 0xA0 是一個16進位數字  換算成 十進位其實就等於 160 。   高位位元組 等於  160 加上 區號,你可以理解為,其實就是 GB2312編碼字元 是從 160 起步的。 就好比 ASCII 編碼是從 0開始  到  127 結束。    

 

我們重新來看下演算法  : 一個GB2312的字元  ==  (0xA0 + 區號,0xA0 + 位號) 。

以上所看,只要我們知道 區位碼(區號和位號)就能算出一個漢字的GB2312編碼數字。 字母a 的區位碼 : 0365 ,也就是區號 03   位號 65 。  按照上面演算法我們算下。 把 0xA0 換成十進位  等於 160。 也就是 (160+03,160+65)    等於   (163,225) 換成 16進位(編碼錶一般都是16進位)  (A3,E1) 。   OK了。   字母a 的gb2312編碼 出來了,拿著   A3E1去  GB2312編碼錶去找這個16進位數字對應的字元吧。 如果你沒看錯的話,沒錯就是對應著 編碼錶上的字母 a 。  

所以, 只要記得 上面公式, 找個工具算出漢字區位碼,然後套進公式裡面算下。就能的到這個字元的GB2312編碼值了。  大家可以自己動手去試試算出上面的漢字 “啊”  的GB2312的編碼值。

 

小總結一下,大家記住:

ASCII 編碼的範圍  --   十進位 => 0 - 127 。  十六進位: 0x00  -  0x7F 。

GB2312編碼的範圍  --   十進位 => 高位位元組:161 - 247 。十六進位:0xA1 - 0xF7  , 低位位元組:  161 - 254 。十六進位:0xA1 - 0xFE  。

 

GBK 編碼:

GB2312 之上的一種擴充編碼,GBK 編碼已經包括了GB2312編碼,並擴充了GB2312編碼,使它能表示更多的字元。  GB2312和GBK 原理一樣,他們區別只是,編碼值範圍不一樣了。 GBK 更大了。 

GB2312 編碼值範圍 :   高位元組從A1到F7,而低位位元組從A1到FE。

GBK 編碼值範圍:  高位元組從81到FE,而低位位元組從40到FE 。

 

以上範圍可以看出。GBK 比  GB2312大很多。   大是大了很多... 不過現在一般項目都用UTF-8編碼了。 接下來將下UTF-8編碼方式

 

UTF-8編碼:

世界上那麼多國家,每個國家的語言都不一樣。一會出個 ASCII 一會出個 GBK 一會出個 XXOO 編碼。那崩潰了。是否能發明一種編碼方式,能很好的表示出所有語言呢。 Unicode編碼就是這樣產生的。這裡我們只講Unicode中得一種實現方式。UTF-8,當然還有其他的實現方式。但對於我們WEB開發來說,並不常用。


ASCII 編碼能很好的表示字母、數字等。所以UTF-8 就在它的基礎上進行了一下擴充。  按照慣例,我們還是先看下 Unicode編碼 表(UTF8編碼錶。木有。我們需要掌握如何從Unicode 轉換成 utf8) 

學習這節的目的

掌握從Unicode 轉換成utf8編碼的方法  判斷UTF-8下的字元的位元組數。  看下錶:

unicode 位元組位表

unicode 編碼範圍 十進位/十六進位

UTF-8 位元組模板二進位/十六進位

位元組數

(0)000000 – (127)00007F 

0xxxxxxx(00-7F)

一位元組

(128)000080 – (2047)0007FF 

110xxxxx(C2-DF)      10xxxxxx

兩個位元組

(2048)000800 – (55295)00D7FF (57344)00E000 – (65535)00FFFF 

1110xxxx(E0-EF)     10xxxxxx     10xxxxxx

三個位元組

(65536)010000 – (1114111)10FFFF 

11110xxx(F0-F4) 10xxxxxx 10xxxxxx 10xxxxxx

四個位元組

 

這個表很重要,記下這個表就基本瞭解了UTF-8 是怎麼一回事。  UTF-8 一共能用四個位元組來表示。 但一般字元呢基本用三個位元組就能滿足了。 

一個位元組等於8位。這個大家都知道。   從 00000000   -   11111111    這個就是一個位元組的數值範圍。   換算成十進位就是  0  -  255 。  懂了這個我們繼續往下講。


繼續看上圖,   我們慢慢講:

UTF-8中之 一位元組:

在UTF-8裡面對ASCII 編碼進行了保留然後再它之上進行了擴充補充。 一個位元組 存的 還是字母呀  數字呀 和ASCII 編碼一樣。所以 編碼範圍也是   0  -  127 。 

有點同學納悶為啥是  127 呢。 一個位元組換算成二進位不是 255嗎。  因為一位元組的時候,第一位給借去了,第一位的值為 固定為0   。大家看上圖第一行 “UTF-8位元組模板“ 這一列 就明白了。所以其實只有7位是用來表示字元。那麼 換算了下 7位  的二進位 就只有   0  -  127  了。 這個幾乎和ASCII 編碼一樣,  想知道0  -  127 都分別對應了什麼字元。 看ASCII 編碼錶呀。

UTF-8 之兩位元組:

一個位元組 8位,兩個位元組就16位了。哇。值更大了,能表示的字元更多了。所以什麼希臘字母呀、拉丁字母呀等都可以用兩位元組來表示了。 看 第二行的 ”UTF-8位元組模板“ 這一列 。110xxxxx      10xxxxxx          一共有16位, 每8位一個位元組。 大家知道,在一個位元組的時候,第一位是不能用的。  兩個位元組的時候稍微不同了。 在兩個位元組的時候, 第一個位元組的前三位給借去了,同時第二個位元組的前兩位也是給借去了。    恩在這裡,我們只要明白一個地方就行。   UTF-8 編碼中 當字元是兩個位元組表示的時候,第一個位元組的編碼值範圍是多少。    第一個位元組是 : 110xxxxx   。   那麼也就是範圍從   11000000  -  11011111     換成十六進位範圍是   C2  -   DF  。   恩懂這一點,就足夠了。  以後遇到 寫 UTF-8編碼 下的 截取 函數 、統計長度函數 就不用怕了。


UTF-8 之三位元組:

三個位元組表示,是我們用的最多的,因為俺們寫中文的嘛。  不過這裡注意下就是 ,三位元組下的借位情況。  繼續看上圖 。   1110xxxx(E0-EF)     10xxxxxx     10xxxxxx     看到了嗎。你懂的~ 如果還不懂...還是繼續重頭看起吧。  UTF-8 下 一個字元三位元組的。  第一個位元組 的範圍是多少? 這個必須弄清楚。 範圍是從   11100000  -  11101111   十六進位是: E0   -  EF  。  


UTF-8 之四位元組:

這個遇到真不多。 不過道理  你真懂了。我就不說了

好了。我們完成了一個目標了 : 判斷UTF-8下的字元的位元組數。比如以後開發你遇到:

對於這段文字 :  "逆雪寒之PHP拾遺"        。 我要在UTF-8下統計它的字元長度  和  實現截取字元竄。   應該沒那麼心慌了。  當然有人說,統計字元長度和截取中文字元竄不是很簡單嗎。mb_strlen 、 mb_substr 。 的確是可以呀。 但我想我們要知其然知其所以然 。 我們的目標是 PHP產品級研發。 不是 PHP企業網站級研發  -_-! 。 


接下來完成另外一個目標: 掌握從Unicode 轉換成utf8編碼的方法 


我們繼續看 unicode 位元組位表  。 看第一列    unicode 編碼範圍 。 四個位元組,所以就有四個範圍 。 看這個  (0)000000 – (127)00007F       十進位從 0 開始到  127  。這個就是第一位元組的unicode 範圍。  其他的也是同一個意思。 

明白了上面講的以後,現在開始講 unicode 編碼轉換 UTF-8的流程: 

我們用 “啊” 這個漢字為例,它的 Unicode 編碼是  U+554A (怎麼知道的。查 unicode 編碼錶呀 大哥...) 。 然後我們轉成UTF-8 :

U+554A 換成十進位是  21834  。 比對  上面的  unicode 位元組位表 的第一列  。看到  21834 是在  三個位元組的  (2048)000800 – (55295)00D7FF  範圍之內。  因為  “啊”  在UTF-8 裡是三個位元組的。

三個位元組 的UTF-8模板  是(看 unicode 位元組位表 )   1110xxxx      10xxxxxx     10xxxxxx      。

"啊“  的   U+554A換算成二進位是 : 101 010101 001010

把15位二進位按照順序的填入(不足最後補0)  三位元組的 UTF-8 模板裡面  。也就是    11100101  10010101  10001010   。    第一位元組 不足位,所以最前位補0.

 最後結果 ,0xE5  0x95  0x8A  這三個就是 ”啊“  字的UTF-8編碼了。

<?php

$v1='E5';
$v2='95';
$v3='8A';
$v1=base_convert($v1, 16, 2);
$v2=base_convert($v2, 16, 2);
$v3=base_convert($v3, 16, 2);
echo $v1.$v2.$v3."************<br>";

$sss=$v1.$v2.$v3; 111001011001010110001010

?>

0101010101001010****21834************啊


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.