2010年1月11日 星期一

Unicode encoding 基本概念

參考來源:

http://docs.python.org/howto/unicode.html

http://www.joelonsoftware.com/articles/Unicode.html

最近在學Python,到了Python網站上逛逛時,發現Unicode How to 這篇文章後,才算是對所謂的 unicode、encoding的觀念有比較正確的了解。

一般大家對Unicode的了解是,它是用來解決原本ASCII編碼無法支援英語系以外字元的問題所開發出來的編碼方式。依照它的歷史演進,有 UTF-16、UTF-8…等等的不同implementation。一般人不了解的是,Unicode定義的只是一個個的 code point,並將這個code point指向某個字元,這裡的字元是一個抽象的概念。如 A 和 A 都對應到同一個code point;而A與 a則對應到不同的code point。為了與ASCII相容,原本 0~127的ASCII碼到了Unicode中,還是代表同樣的字元,如0x61在Unicode或ASCII中,都是對應到 a這個字元。

Encoding的概念

接下介紹encoding這個觀念。前面說Unicode是定義一個個的抽象的 code point對應,那如何把一連串的Unicode 字串儲存到電腦的記憶體或檔案中呢? 比方說,若用Unicode表示Hello這個字串,就會變成這樣

  H        e             l            l          o
U+0048 U+0065 U+006C U+006C U+006F

當要將這個字串儲存到電腦的記憶中時,需要把每個字元的Unicode碼,轉換成一個個實際的 byte 資料,這個過程就叫做Encoding。相反地,如果你拿到一連串的byte(可能是瀏覽器抓到的、可能是由檔案讀出來的)時,則需要將這些byte資訊,重新解釋回它所代表的字元,這個過程叫decoding。如下圖(此為示意圖,實際上並不一定這樣作,請接下去看)

image

一般人(也許只有我)都會以為,Unicode的做法只是單純地用2個byte來表示字元(如上圖的例子),這樣就有 2^16 個字元可用,但實際上,並不是這麼簡單。事實上,Unicode有許多不同版本,如UTF-16或UTF-8。UTF-16的作法就是用16個bit來代表一個字元;而UTF-8則是使用8個bit來encode字元。其中UTF-16是較早期的版本,它在推出時,並不受到喜愛,原因就在上面的例子

           它會造成空間的浪費!!!

因為當時,internet還沒有像現在這麼恐怖,所以電腦還是在阿兜阿 的世界比較風行,對於阿阿兜阿來說,他們根本用不到 ASCII以外的字元,如果為了要apply UTF-16,原本只要1個byte(0x48h) 就可以代表H這個字元,用了UTF-16後,要用2個byte(0x0048h)來代表,而第二個byte中所有的bit的值都為零! 等於是浪費了一個byte。這對於那些阿兜阿根本不make sense,所以使用的人很少。直到後來UTF-8的出現,Unicode才被大家所接受。那麼UTF-8是如何使用8個bit來做encoding的工作呢?UTF-8使用的編碼規則如下:

  1. 如果code point < 128,則用單一個byte來表示該字元(也就是,原本ASCII的字元完全不受影響)
  2. 如果 128<=code point <=0x7ff,則用2個值介於 128 ~255的 byte來表示
  3. 如果code point> 0x7ff,則用3個或4個 值介於 128~255的byte來表示

如此一來,UTF-8既不會影響原本使用ASCII編碼的使用者,又可以將其它語言的字元都涵蓋進來,因此成為現在Unicode編碼的主流

瀏覽器如何知道要用何種編碼?

在瀏覽網頁時,有的時候會出現無法正常顯示頁面的狀況,這是因為瀏覽器用了錯誤的編碼機制來解讀資料。那瀏覽器是如何決定要如何解讀收到的資料呢?答案就是 Content-Type:text/plain;charset=”UTF-8”這個資訊。

COntent-Type這個資訊可以放在HTTP的header,也可以放在 HTML的 <head>…</head>中,如

<html>
  <head>
  <meta http-equiv="Content-Type"   content="text/html; charset=utf-8">

要知道瀏覽器收到的資料只是一連串的byte資訊,需要另外告訴瀏覽器這個byte資訊是用那一種編碼方式 encode而成的,這樣它才能以正確的編碼機制來解讀Byte的資訊。如果HTTP header或 HTML的<head>…</head>中沒有給定Content-Type資訊時,瀏覽器會試著去猜可能的編碼方式,然後用該編碼方式來做解讀。既然是用猜的,就可能會有猜錯的狀況,結果就是顯示出亂碼了!

2010年1月6日 星期三

在python安裝新的package

一般Python的 package會有提供 setup的 script,不過要使用這個script前,需先安裝 setuptools這個套件,此套件可以在 http://pypi.python.org/packages/2.6/s/setuptools/ 這個網址找到。

安裝setuptools套件後,就可以參照所要安裝的套件中的README檔案的指示,用新套件提供的setup.py來安裝了,如下

C:\Package_Source_DIR>C:\Python26\python.exe   setup.py   install