Unicode和Python的中文處理

來源:互聯網
上載者:User

Unicode和Python的中文處理

http://blog.csdn.net/tingsking18/archive/2009/03/29/4033645.aspx

  在Python語言中,Uincode字串處理一直是一個容易讓人迷惑的問題。許多Python愛好者經常因為搞不清Unicode、UTF-8還有其它許許多多的編碼之間的區別而大傷腦筋。筆者曾經也是這“傷腦筋一族”的成員,但經過半年多的努力,現在終於初步弄清楚其中的一些關係。現將其整理如下,與各位同仁同享。同時也希望能借這篇短文拋磚引玉,吸引更多真正的高手加入進來,共同完善我們的Python中文環境。

  本文所提到的各種觀點,一部分是查閱資料所得,還有一部分是筆者利用已有各種編碼資料用“猜測加驗證”法得到。筆者自問才疏學淺,其中怕是藏有不少錯誤。各位看官中不乏高手,如果有哪一位發現其中哪裡有錯,萬望各位高人不吝賜教。筆者自己丟醜事小,觀點錯誤誤了別人事大,因此各位大可不必顧忌筆者的面子問題。

第一節 文字編碼和Unicode標準

  要解釋Unicode字串就必須先從什麼是Unicode編碼開始說起。眾所周知,文本顯示一直是電腦顯示功能必須解決的基本問題。而電腦並不識字,它實際上是把文本看做是一串“圖片”,每張“圖片”對應一個字元。每個電腦程式在顯示文本時,必須藉助一個記錄這個文字“圖片”如何顯示的“圖片”集合,從中找到每一個字元對應“圖片”的資料,並依樣畫葫蘆地把這個字“畫”到螢幕上。這個“圖片”就被稱為“字模”,而記錄字模顯示資料的集合就被稱為“字元集”。為方便程式尋找,每個字元的字模資料在字元集中必須是有序排列的,而且每個字元都會被分配一個獨一無二的ID,這個ID就是字元的編碼。而在電腦進行字元資料處理時,總是用這個編碼代表它表示的那個字元。因此,一個字元集就規定了一組電腦能夠處理的字元資料。顯然,不同國家指定的字元集大小不同,相應的字元編碼也不同。

  在電腦曆史上,最為廣泛使用的標準化字元集當首推ASCII字元集。它實際上是美國制訂的標準,針對北美使用者開發。它使用7個二進位位編碼,可以表示128個字元。這個字元集最終被ISO組織正式採納為國際標準,並且大量應用在各種電腦體繫上。現如今,所有PC機的BIOS中都內含了ASCII字元集的字模,其深入人心可見一斑。

  但是,當電腦在各個國家大規模普及時,ASCII編碼的局限性就暴露出來了:它的字元空間實在有限,無法容納更多的字元,可是絕大多數語言需要使用的字元數目都遠不止128個。為了能正確處理本國文字,各個國家官方或民間紛紛開始了設計本國文字編碼集的工作,並且最終湧現出許許多多針對各個國家文字的字元編碼,如針對西歐字元的ISO-8859-1編碼,針對簡體中文的GB系列編碼,還有針對日文的SHIFT-JIS編碼等等。同時,為了保證各個新的字元集能夠相容原本的ASCII文本,大多數字元集不約而同地都將ASCII字元作為自己前128個字元,並使其編碼與ASCII編碼一一對應。

  這樣一來,各國文字的顯示問題是解決了,可是又帶來一個新的問題:亂碼。不同國家、地區使用的字元集通常沒有統一的規範進行約束,因此各個字元集編碼往往互不相容。同一個字在兩個不同的字元集中編碼一般不同;而同一個編碼在不同的字元集中對應的字元也不一樣。一段用編碼A編寫的文本在一個只支援編碼B的系統上往往會被顯示成一堆亂七八糟的字元。更糟糕的是,不同字元集使用的編碼長度往往也不相同,那些只能處理單位元組編碼的程式在遇到雙位元組甚至是多位元組編碼的文本時,往往因為不能正確處理而產生了臭名昭著的“半個字”問題。這使得本已經混亂不堪的局面更是亂成了一團粥。

  為了一勞永逸地解決這些問題,業界許多大公司和組織聯合提出了一個標準,這就是Unicode。Unicode實際上是一種新的字元編碼體系。它對字元集中的每個字元用兩個位元組長的ID號進行編碼,從而規定出一個可容納多達65536個字元的編碼空間,並且將現今國際上各國編碼中的常用字盡數收入罄中。由於在設計編碼時有了周全的考慮,Unicode很好地解決了其它字元集在進行資料交流時的亂碼和“半個字”問題。同時,Unicode的設計者充分考慮到現今大量字模資料使用的仍是各國制訂的各種編碼這一現實,提出了“將Unicode作為內部編碼”的設計理念。也就是說,字元顯示程式依然使用原先的編碼和代碼,而應用程式的內部邏輯使用的將是Unicode。當要進行文字顯示時,程式總是將Unicode編碼的字串轉換成原本的編碼進行顯示。這樣,大家就不必為了使用Unicode而重新設計字模資料體系了。同時,為了與各國已經制訂的編碼相區別,Unicode的設計者將Unicode稱為“寬字元編碼”(wide characters encodings),而各國制訂的編碼習慣上被稱為“多位元組編碼”(multi bypes encodings)。時至今日,Unicode體系又引入了四位元組的擴充編碼,並且逐漸與與UCS-4,也就是ISO10646編碼規範合流,希望有朝一日能夠用ISO10646體系統一全世界所有的文字編碼。

  Unicode體系甫一出世便被大家寄予厚望,並被迅速接受為ISO認可的國際標準。但是,Unicode在推廣過程中卻遭到了首先是歐美使用者的反對。他們反對的理由非常簡單:歐美使用者原本使用的編碼都是單位元組長的,雙位元組的Unicode處理引擎無法處理原本的單位元組資料;而如果要把現有的單位元組文本全部轉換成Unicode,工作量就太大了。再說,如果所有的單位元組編碼文本都被轉換成雙位元組的Unicode編碼,他們所有的文本資料佔用的空間都會變成原來的兩倍,而且所有的處理常式都要被重新編寫。這個開銷他們無法接受。

  雖然Unicode是國際認可的標準,但是標準化組織不可能不考慮歐美使用者這個最大的電腦使用群體的要求。於是在各方磋商之下,一個Unicode的變種版本產生了,這就是UTF-8。UTF-8是一個多位元組的編碼體系,它的編碼規則如下:

  1、UTF-8編碼分為四個區:
    一區為單位元組編碼,
      編碼格式為:0xxxxxxx;
      對應Unicode:0x0000 - 0x007f
    二區為雙位元組編碼,
      編碼格式為:110xxxxx 10xxxxxx;
      對應Unicode:0x0080 - 0x07ff
    三區為三位元組編碼,
      編碼格式為:1110xxxx 10xxxxxxx 10xxxxxx
      對應Unicode:0x0800 - 0xffff
    四區為四位元組編碼,
      編碼格式為:11110xxx 10xxxxxxx 10xxxxxx 10xxxxxx
      對應Unicode:0x00010000 - 0x0001ffff
    五區為五位元組編碼,
      編碼格式為:111110xx 10xxxxxxx 10xxxxxxx 10xxxxxxx 10xxxxxxx
      對應Unicode:0x00200000 - 0x03ffffff
    六區為六位元組編碼,
      編碼格式為:111110x 10xxxxxxx 10xxxxxxx 10xxxxxxx 10xxxxxxx 10xxxxxxx
      對應Unicode:0x04000000 - 0x7fffffff

   其中,一、二、三區對應Unicode的雙位元組編碼區,而四區則針對Unicode的四位元組擴充部分(按照該定義,UTF-8還有五區和六區,但筆者並未在GNU glibc庫中發現,不知為何);

  2、各個區按照一、二、三、四、五、六順序排列,其對應位置上的字元與Unicode保持相同;

  3、不可顯示的Unicode字元編碼為0位元組,換言之,它們沒有被收入UTF-8(這是筆者從GNU C庫注釋中得到的說法,可能與實際情況不符);

  按照UTF-8編碼規則我們不難發現,其一區的128個編碼實際上就是ASCII編碼。所以UTF-8的處理引擎可以直接處理ASCII文本。但是,UTF-8對ASCII編碼的相容是以犧牲其它編碼為代價的。比如,原本中、日、韓三國文字基本上都是雙位元組編碼,但它們在Unicode編碼中的位置對應到UTF-8中的三區,每一個字元編碼要三個位元組長。換句話說,如果我們把所有現有的中、日、韓三國編碼的非ASCII字元文本資料轉換成UTF-8編碼,則其大小都會變成原來的1.5倍。

  雖然筆者個人認為UTF-8的編碼方式顯得有些不夠公平,但它畢竟解決了ASCII文本到Unicode世界的過渡問題,所以還是贏得了廣泛的認可。典型的例子是XML和Java:XML文本的預設編碼就是UTF-8,而Java原始碼實際上就可以用UTF-8字元編寫(JBuilder的使用者應該有印象)。另外還有開源軟體世界中大名鼎鼎的GTK 2.0,它使用UTF-8字元作為內部編碼。

  說了這麼多,似乎話題有些扯遠了,許多Python愛好者可能已經開始著急:“這和Python有什麼關係呢?”好的,現在我們就把視線轉到Python的世界來。

第二節 Python的Unicode編碼系統

  為了正確處理多語言文本,Python在2.0版後引入了Unicode字串。從那時起,Python語言中的字串就分為兩種:一種是2.0版之前就已經使用很久的傳統Python字串,一種則是新的Unicode字串。在Python語言中,我們使用unicode()內建函數對一個傳統Python字串進行“解碼”,得到一個Unicode字串,然後又通過Unicode字串的encode()方法對這個Unicode字串進行“編碼”,將其“編碼”成為傳統Python字串以上內容想必每一個Python使用者都是爛熟於胸了。但是你可知道,Python的Unicode字串並不是真正意義上的“Unicode編碼的字串”,而是遵循一種自己特有的規則。這個規則的內容簡單得很:

  1、ASCII字元的Python Unicode編碼與它們的ASCII編碼相同。也就是說,Python的Unicode字串中ASCII文本仍然是單位元組長度編碼;

  2、ASCII字元以外的字元,其編碼就是Unicode標準編碼的雙位元組(或四位元組)編碼。
    (筆者猜想,之所以Python社群要制訂如此古怪的標準,可能是想保證ASCII字串的通用性吧)

  通常在Python應用中,Unicode字串都是作為內部處理時使用,而終端顯示工作則由傳統的Python字串完成(實際上,Python的print語句根本無法列印出雙位元組的Unicode編碼字元)。在Python語言中,傳統Python字串就是所謂的“多位元組編碼”字串,用於表示各種被“編碼”成為具體字元集編碼的字串(比如GB、BIG5、KOI8-R、JIS、ISO-8859-1,當然也有UTF-8);而Python Unicode字串則是“寬字元編碼”字串,表示從具體字元集編碼中“解碼”出來的Unicode資料。所以通常情況下,一個需要用到Unicode編碼的Python應用往往會以如下方式處理字串資料:

def foo(string, encoding = "gb2312"):# 1. convert multi-byte string to wide character stringu_string = unicode(string, encoding)# 2. do something...# 3. convert wide character string to printable multi-byte stringreturn u_string.encode(encoding)

 

  我們可以舉出一個例子:經常在Red Hat Linux環境中使用PyGTK2進行XWindow編程的Python同道可能早就發現過這樣的情況:如果我們直接寫出如下語句:

import pygtkpygtk.require('2.0')import gtkmain = gtk.Window() # create a windowmain.set_title("你好") # NOTICE!

 

  這樣的語句在執行時會在終端上出現這樣的警告:
  Error converting from UTF-8 to 'GB18030': 轉換輸入中出現無效字元序列並且程式視窗標題不會被置為“你好”;

  但如果使用者安裝了中文的codec,並將上文的最後一句改為:

u_string = unicode('你好','gb2312')main.set_title(u_string)

則程式視窗標題將會被正確地設定為“你好”。這是為什麼呢?

  原因很簡單。gtk.Window.set_title()方法總是將自己接收的標題字串看做是一個Unicode字串。PyGTK系統在接收到使用者的main.set_title()這一請求時,將得到的字串在某處做了如下處理:

class Window(gtk.Widget):...def set_title(self, title_unicode_string):...# NOTICE! unicode -> multi-byte utf-8real_title_string = title_unicode_string.encode('utf-8')...# pass read_title_string to GTK2 C API to draw the title...

 

  我們看到,字串title_unicode_string在程式內部被“編碼”成了一個新的字串:real_title_string。顯然,這個real_title_string是一個傳統Python字串,而它的編碼用的是UTF-8。在上一節中筆者曾經提到過,GTK2的內部使用的字串都是按UTF-8編碼的,所以,GTK2核心系統在接收到real_title_string後可以正確顯示出標題來。

  那麼,如果使用者輸入的標題是ASCII字串(比如:“hello world”),又當如何?我們回想一下Python Unicode字串的定義規則就不難發現,如果使用者的輸入是ASCII字串,則對其進行重編碼得到的就是其自身。也就是說,如果title_unicode_string的值是ASCII字串,則real_title_string與title_unicode_string的值將完全一致。而一個ASCII字串也就是一個UTF-8字串,把它傳遞給GTK2系統不會有任何問題。

  以上我們舉的例子是關於Linux下的PyGTK2的,但類似的問題不僅出現在PyGTK中。除了PyGTK之外,現今各種Python綁定的圖形包,如PyQT、Tkinter等,多多少少都會遇到與Unicode處理有關的問題。

  現在我們弄清了Python的Unicode字串編碼機制,但是我們最想知道的問題還是沒有解決:我們如何才能讓Python支援用Unicode處理中文呢?這個問題我們將在下一節說明。

第三節 如何讓Python的Unicode字串支援中文

  看完這一節的標題,有一些Python同道們可能會有些不以為然:“為什麼一定要用Unicode處理中文呢?我們平時用傳統Python字串處理得不是也不錯嗎?”的確,其實在一般情況下像字串串連、子串匹配等操作用傳統Python字串也就足夠了。但是,如果涉及到一些進階的字串操作,比如包含多國文字的Regex匹配、文本編輯、運算式分析等等,這些大量混雜了單位元組和多位元組文本的操作如果用傳統字串處理就非常麻煩了。再說,傳統字串始終無法解決那該死的“半個字”問題。而如果我們可以使用Unicode,則這些問題都可以迎刃而解。所以,我們必須正視並設法解決中文Unicode的處理問題。

  由上一節的介紹我們知道,如果要想利用Python的Unicode機制處理字串,只要能夠擁有一個能夠把多位元組的中文編碼(包括GB編碼系列和BIG5系列)和Unicode編碼進行雙向轉換的編碼/解碼模組就可以了。按照Python的術語,這樣的編碼/解碼模組被稱為codec。於是接下來的問題就變成了:我們該如何編寫這樣一個codec?

  如果Python的Unicode機制是寫入程式碼在Python核心中的話,那麼給Python添加一個新的codec就將是一項艱苦卓絕的工作了。幸虧Python的設計者們沒有那麼傻,他們提供了一個擴充性極佳的機制,可以非常方便地為Python添加新的codecs。

  Python的Unicode處理模組有三個最重要的組成部分:一是codecs.py檔案,二是encodings目錄,三是aliases.py檔案。前兩者都位於Python系統庫的安裝目錄之中(如果是Win32發行版,就在$PYTHON_HOME/lib/目錄下;如果是Red Hat Linux,就在/usr/lib/python-version/目錄下,其它系統可以照此尋找),而最後一個則位於encodings目錄下。接下來,我們分別對這三者加以說明。

  先來看看codecs.py檔案。這個檔案定義了一個標準的Codec模組應有的介面。其具體內容大家可以在自己的Python發行版中找到,在此不再贅述。按照codecs.py檔案的定義,一個完整的codec應該至少擁有三個類和一個標準函數:

  1、Codec類

  用途:
    用於將使用者傳入的緩衝區資料(一個buffer)作為一個傳統Python字串,並將其“解碼”為對應的Unicode字串。一個完整的Codec類定義必須提供Codec.decode()和Codec.encode()兩個方法:

Codec.decode(input, errors = "strict")

  用於將輸入的資料看做是傳統Python字串,並將其“解碼”,轉換成對應的Unicode字串。

  參數:

  input:       輸入的buffer(可以是字串,也可以是任何可以轉換成字串表示的對象)
  errors:      發生轉換錯誤時的處理選擇。可選擇如下三種取值:
  strict(預設值):  如果發生錯誤,則拋出UnicodeError異常;
  replace:      如果發生錯誤,則選取一個預設的Unicode編碼代替之;
  ignore:      如果發生錯誤,則忽略這個字元,並繼續分析餘下的字元。

  傳回值:
    一個常數列表(tuple):首元素為轉換後的Unicode字串,尾元素為輸入資料的長度。

Codec.encode(input, errors = "strict")

  用於將輸入的資料看做是Unicode字串,並將其“編碼”,轉換成對應的傳統Python字串。

  參數:

  input:輸入的buffer(通常就是Unicode字串)
  errors:發生轉換錯誤時的處理選擇。取值規則與Codec.decode()方法相同。

  傳回值:
    一個常數列表(tuple):首元素為轉換後的傳統Python字串,尾元素為輸入資料的長度。

  2、StreamReader類(通常應該繼承自Codec類)

  用於分析檔案輸入資料流。提供所有對檔案對象的讀取操作,如readline()方法等。

  3、StreamWriter類(通常應該繼承自Codec類)

  用於分析檔案輸出資料流。提供所有對檔案對象的寫入操作,如writeline()方法等。

  5、getregentry()函數

  即“GET REGistry ENTRY”之意,用於擷取各個Codec檔案中定義的四個關鍵函數。其函數體統一為:

def getregentry():return tuple(Codec().encode,Codec().decode,StreamReader,StreamWriter)

  在以上提到的所有四個類中,實際上只有Codec類和getregentry()函數是必須提供的。必須提供前者是因為它是實際提供轉換操作的模組;而後者則是Python系統獲得Codec定義的標準介面,所以必須存在。至於StreamReader和StreamWriter,理論上應該可以通過繼承codecs.py中的StreamReader和StreamWriter類,並使用它們的預設實現。當然,也有許多codec中將這兩個類進行了改寫,以實現一些特殊的定製功能。

  接下來我們再說說encodings目錄。顧名思義,encodings目錄就是Python系統預設的存放所有已經安裝的codec的地方。我們可以在這裡找到所有Python發行版內建的codecs。習慣上,每一個新的codec都會將自己安裝在這裡。需要注意的是,Python系統其實並不要求所有的codec都必須安裝於此。使用者可以將新的codec放在任何自己喜歡的位置,只要Python系統的搜尋路徑可以找得到就行。

  僅僅將自己寫的codec安裝在Python能夠找到的路徑中還不夠。要想讓Python系統能找到對應的codec,還必須在Python中對其進行註冊。要想註冊一個新的codec,就必須用到encodings目錄下的aliases.py檔案。這個檔案中只定義了一個雜湊表aliases,它的每個鍵對應著每一個codec在使用時的名稱,也就是unicode()內建函數的第二個參數值;而每個鍵對應的值則是一個字串,它是這個codec對應的那個處理檔案的模組名。比如,Python預設的解析UTF-8的codec是utf_8.py,它存放在encodings子目錄下,則aliases雜湊表中就有一項表示其對應關係:

'utf-8' : 'utf_8', # the module `utf_8' is the codec for UTF-8

 

同理,如果我們新寫了一個解析‘mycharset’字元集的codec,假設其編碼檔案為mycodec.py,存放在$PYTHON_HOME/lib/site-packages/mycharset/目錄下,則我們就必須在aliases雜湊表中加入這麼一行:

'mycharset' : 'mycharset.mycodec',

這裡不必寫出mycodec.py的全路徑名,因為site-packages目錄通常都在Python系統的搜尋路徑之中。

  Python解譯器在需要分析Unicode字串時,會自動載入encodings目錄下的這個aliases.py檔案。如果mycharset已經在系統中註冊過,則我們就可以像使用其它內建的編碼那樣使用我們自己定義的codec了。比如,如果按照上面的方式註冊了mycodec.py,則我們就可以這樣寫:

my_unicode_string = unicode(a_multi_byte_string, 'mycharset')print my_unicode_string.encode('mycharset')

  現在我們可以總結一下要編寫一個新的codec一共需要那些步驟:

  首先,我們需要編寫一個自己的codec編碼/解碼模組;

  其次,我們要把這個模組檔案放在一個Python解譯器可以找到的地方;

  最後,我們要在encodings/aliases.py檔案中對其進行註冊。

  從理論上說,有了這三步,我們就可以將自己的codec安裝到系統中去了。不過這樣還不算完,還有一個小問題。有時候,我們出於種種原因,不希望隨便修改自己的系統檔案(比如,一個使用者工作在一個集中式的系統中,系統管理員不允許別人對系統檔案進行修改)。在以上介紹的步驟中,我們需要修改aliases.py檔案的內容,這是一個系統檔案。可如果我們不能修改它,難道我們就不能添加新的codec嗎?不,我們當然有辦法。

  這個辦法就是:在運行時修改encodings.aliases.aliases雜湊表的內容。

  還是使用上面那個假設,如果使用者工作系統的管理員不允許使用者把mycodec.py的註冊資訊寫入aliases.py,那麼我們就可以如此處理:

  1、將mycodec.py放在一個目錄下,比如/home/myname/mycharset/目錄;

  2、這樣編寫/home/myname/mycharset/__init__.py檔案:

import encodings.aliases# update aliases hash mapencodings.aliases.aliases.update({\'mycodec' : 'mycharset.mycodec',\}}

  以後每次要使用Python時,我們可以將/home/myname/加入搜尋路徑,並且在使用自己的codec時預先執行:

import mycharset # execute the script in mycharset/__init__.py

 

  這樣我們就可以在不改動原有系統檔案的情況下使用新的codecs了。另外,如果藉助Python的site機制,我們還可以讓這個import工作自動化。如果大家不知道什麼是site,就請在自己的Python互動環境中運行:

import siteprint site.__doc__

瀏覽一下site模組的文檔,即可明白個中技巧。如果大家手頭有Red Hat Linux v8,v9,還可以參考一下Red Hat的Python發行版中附帶的日文codec,看看它是如何?自動載入的。也許不少同道可能找不到這個日文的codec在哪裡,這裡列出如下:

Red Hat Linux v8:在/usr/lib/python2.2/site-package/japanese/目錄下;  Red Hat Linux v9:在/usr/lib/python2.2/lib-dynload/japanese/目錄下;

 

提示:請Red Hat使用者注意site-packages目錄下的japanese.pth檔案,結合site模組的文檔,相信馬上就能豁然開朗。

結束語

  記得當初筆者在Dohao論壇上誇下海口:“如果可以的話,我可以為大家編寫一個(中文模組)”,現在回想起來,不禁為自己當初的不知天高地厚而汗顏。一個把自己所有的的時間都花在學習上,一個學期只學七門課程,還落得個兩門課不及格的傻瓜研究生,哪裡有什麼資格在大家面前如此囂張。現如今,第二個學期由於這兩門課的緣故負擔陡增(十門課呀!),家中老父老母還眼巴巴地等著自己的兒子能給他們掙臉。要想在有限的時間之內,既保證學習,又保證工作(我要承擔導師的課程輔導工作,同時還有一個學校的教學改革方案需要我在其中挑大樑),已經是疲於應付,再加上一個中文模組……唉,請恕筆者分身乏術,不得不食言。

  因此,筆者鬥膽,在此和盤托出自己這半年以來的心得,只希望能夠找到一批,不,哪怕是一個也好,只要是對這個項目感興趣的同道中人,能夠接下筆者已經整理出來的知識,把一個完整的(至少應該包含GB、BIG5、筆者個人認為甚至還應包括HZ碼)中文模組編寫出來,貢獻給大家(不論是有償的還是無償的),那就是我們廣大Python愛好者之福了。另外,Python的發行版至今尚未包括任何中文支援模組。既然我等平日深愛Python,如果我們的工作能因此為Python的發展做出一點貢獻,何樂而不為呢?

附錄 幾個小小提示

  1、LUO Jian兄已經編寫了一個非常不錯的中文模組(Dohao上有連結,檔案名稱是showfile.zip,這個模組比我已經寫完的草稿版本要快得多),同時支援GB2312和GB18030編碼,可惜不支援BIG5。如果大家有興趣,可以下載這個模組研究一下;

  2、和其它字元集編碼相比,中文模組有其特殊性,那就是其海量的字元數目。一些相對較小的字元集還好說,比如GB2312,可以利用雜湊表尋找。而對於巨大的GB18030編碼,如果簡單地將所有資料製成一個特大的編碼對照表,則查詢速度會慢得讓人無法容忍(筆者在編寫模組時最頭疼的就是這一點)。如果要編寫一個速度上能讓人滿意的codec,就必須考慮設計某種公式,能夠通過簡單地運算從一種編碼推算出另一種來,或者至少能推算出它的大概範圍。這就要求程式員要能對整個編碼方案做統計,設法找到規律。筆者認為,這應該是編寫中文模組時的最大痛點。或許是數學功底實在太差的緣故,筆者費盡心機也未能找出一個規律來。希望能有數學高手不吝賜教;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.