【閒聊】遺禍萬年的中文編碼



贊助商連結


頁 : [1] 2

VicLin
2005-06-12, 04:42 PM
在處理Php文章管理程式時 發現某些字被加上了一個\
如許功蓋等字 覺得奇怪的同時 於Google搜尋了一些資料
才發現 原來我們用的Big5 大五碼是如此的可悲
以及 過去的種種自以為的作風遺留下的禍害
http://bbs.ee.ntu.edu.tw/boards/Linux/7/9/58.html

贊助商連結


阿 土
2005-06-12, 06:30 PM
GB2312 完全沒這方面的問題 , BIG5 卻是如此
所以我也是對 BIG5 的制訂有些抱怨
這對於程式撰寫人員真是一種痛 , 還必須注意這方面的問題

我常繁體化對岸的 php 程式
字詞繁體化是不困難
每次遇到的都是 big5 衝碼
不管是搜尋或是新增資料都會出問題

Picasso
2005-06-13, 03:48 PM
嗚.....好艱深的討論。

琥珀
2005-06-13, 04:19 PM
印象中看過這篇。但也不要有 GB2312/GBK 就比較好的想法,不然結果一樣慘。

Big5 - 维基百科,自由的百科全书 (http://zh.wikipedia.org/wiki/Big5),參考看看。如果覺得說明不夠完整,或是對該說明心生不滿,可以點選右邊的"編輯"。

不論是 end-user 也好,developer 也好,真的不要在 Big5 上面打轉了。長期下來做同樣的工作程式碼修補Big5 中文化,能得到多少好處?

阿 土
2005-06-13, 04:33 PM
印象中看過這篇。但也不要有 GB2312/GBK 就比較好的想法,不然結果一樣慘。

並不覺得 GB2312 比較好
只是我的經驗是 GB2312 在 php 程式似乎都不會遇到如同 big5 "許功蓋" 之類衝碼文字的問題
所以有時看到比較好的 GB2312 php 程式想拿來改成繁體中文
通常是 99.999% 會遇到程式相容的問題
gb2312 搜尋功能正常 , big5 搜尋成功之類的文字就找不到了
php 程序中遇到有 "許功蓋" 還會出現錯誤....之類的問題實在很多
可能需要懂得寫 php 程式才有辦法解決

看看這篇文章 : 淺談許蓋功 (http://forum.kmd.com.tw/article5.html) , 可更瞭解 php + big5 衝碼的問題

有位網友寫過 "Big5 字串處理函數" , 不過拿來搭配使用還是有問題 , 不能 100% 解決



Big5 字串處理函數 ver 0.23

快速安裝方法


將 ZIP 檔案解開後 , 放到你喜歡的位置 , 例如 /var/www/htdocs/big5_func
在您的 php 程式以 require , require_once, include , include_once 將 big5_func.inc 引入 , 例如 include("big5_func/big5_func.inc");
寫一支程式試試看 , 例如 : echo big5_addslashes("哈哈abc' '測試許\"); 若正常顯示則代表安裝成功
若您沒有安裝 iconv , 強烈建議您安裝 iconv , 因為這將加快本函數集的運算速度 , 我自己測試在 php4.2.3 win32 版已經提供 iconv , 不過您必須自行修改 php.ini , 將 ;extension=php_iconv.dll 的注解拿掉 , 並且將您 php 安裝目錄下的 dll 目錄下所有檔案拷貝到您的 winnt(或windows)/system32(或system) 目錄下 , 接著您可以重新啟動您的 Web Server , 以 phpinfo() 檢查有沒有載入 iconv , 假如您是 Linux 使用者 , 且是自己編譯 PHP , 那麼您可以到 iconv 網站下載 iconv 套件回來編譯 , 網址是 http://www.gnu.org/software/libiconv/ , 編譯 PHP 時需要指定 --with-iconv=(你的iconv安裝目錄)
另外建議 PHP 4.3 以上版本把 Multi-Byte String Functions 功能打開 , 可以加快某些函速的效能


提供的函數列表與用法範例 : 基本上有許多函數名稱與 PHP 類似, 用法也相同


bool big5_isBig5( string str) : 判斷是否為中文字
範例 : if ( big5_isBig5("A") ) echo "中文" ; else echo "英文";
輸出 : "英文"

string big5_addslashes( string str) : 字串中遇到單引號 ' , 雙引號 ", 斜線 \ 會增加斜線 \ , 若遇到中文字會忽略, 適合放入中文 database,或產生javascript變數用
範例 : <script> alert("<? echo big5_addslashes("許'\功\"); ?>"); </script>
輸出 : 瀏覽器會跳出警告視窗內容為 "許功"
PS : 若使用 MySQL Server 的預設語系是 big5 (--with-charset=big5), 則建議不要使用本函數將字串轉換後增加到資料庫 , 您可以直接使用 mysql_real_esacape_string() 可以更安全與快速 , 另外建議大家使用 ADODB(http://adodb.sourceforge.net/) 這類的抽象程式庫或 Pear DB, 目前都有支援資料庫跳脫字元處理

string big5_stripslashes( string str) : 遇到跳脫字元(\) 會將之刪除 , 但若中文中有一個位元組含有跳脫字元則忽略不處理
範例 : echo big5_stripslashes( big5_addslashes("abc'功\"));
輸出 : "abc\'功"

string big5_addcslashes( string str , string charlist ) : 可以指定字元條件來讓字串中符合條件的字元增加跳脫字元(\) , 若遇到中文字會忽略
範例 : echo big5_addcslashes('foo[ ]許\測試wale ', 'A..z');

string big5_stripcslashes( string str) : 遇到跳脫字元(\) 會將之刪除 , 但若中文中有一個位元組含有跳脫字元則忽略不處理 , 注 : 遇到\0, \a, \b, \f, \n, \r, \t and \v 是把 \ 處理掉 , 而不是真正還原該字元

string big5_substr( string str , int start [, int length] ) : 抓取指定位置的字串 , 若 length 不輸入 , 則由參數 start 指定位置開始抓到字串 str 的最後一個字
範例 : echo big5_substr("測試OK" , 2 , 2);
輸出 : " OK";

string big5_strlen( string str) : 計算字串長度 , 中文或英文皆為一個字
範例 : echo big5_strlen("測試OK");
輸出 : 4

string big5_strtolower( string str) : 將字串內的所有英文字母轉為小寫 , 為何要有這個函數呢 ? 因為某些中文字員確實其中一個 Byte 會是英文字 , 若用 PHP 原本的 strtolower , 則會把這種中文字轉亂了 , 因此使用本函數能保證不把中文變亂 , 以下範例若用 strtolower 去輸出 , 那個 "袍" 字就亂了 ...
範例 : echo big5_strtolower("Kobe Bryan 今天穿紫色戰袍上場");
輸出 : kobe bryan 今天穿紫色戰袍上場

string big5_strtoupper( string str) : 將字串內的所有英文字母轉為大寫

string big5_chunk_split( string str , [int chunklen=76 [, string end="\r\n"] ) : 切割中英文字串 , 預設每 76 個字會被切開並且斷行 , 可以指定 chunklen 來改變切割的字數 , 若設定 end 則可以改變每一個切割單位最後要加什麼字串
範例 : echo big5_chunk_split("哈哈,你好笨" , 2 , "/");
輸出 : "哈哈/,你/好笨"

int big5_strpos( string haystack , string needle , [, int offset] ) : 在字串 haystack中搜尋符合 needle 的第一個位置 , offset 是指定要從第幾個字開始搜尋 , 請注意 , 若搜尋不到字串 , 會傳回 false , 若搜尋到的字串在第一個字就找到 , 會傳回 0
範例1 : echo big5_strpos( "你真的好笨勒..." , "笨");
輸出 : 4
範例2 : if( !is_integer(big5_strpos("你好笨" , "CCC") )) echo "Not Found";
輸出 : "Not Found"

int big5_strrpos( string haystack , char needle) : 在字串 haystack中搜尋符合 needle 的最後一個位置 , 若搜尋到的字元(中文字算一個字元)在第一個字就找到 , 會傳回 0 , 若找不到 needle 字元傳回 false , 請注意 , 按照 PHP 手冊的 strrpos 規範 , needle 必須為單一字元, 若 needle 為整數 , 則會將該整數轉換為 ASCII 對應的字元 , 例如 needle=65 , 則 needle='A' , 若 needle=0xA440 , 則 needle='一'
範例1 : echo big5_strrpos( "你真的好笨好笨勒..." , "笨");
輸出 : 6
範例2 : if( !is_integer(big5_strrpos("你好笨" , "哇") )) echo "Not Found";
輸出 : "Not Found"

string big5_str_replace( string search , string replace , string subject) : 搜尋字串並取代 , subject 是原來的字串 , search 是搜尋的字串 , replace 是搜尋後要取代的字串
範例 : echo big5_str_replace("%姓名%" , "Mary" , "Hi , %姓名% 你好啊");
輸出 : "Hi , Mary 你好啊"

int big5_stroke( string str) : 計算單一中文筆劃數

string big5_unicode( string str) : 將字串 str 轉為網頁用的 Unicode , 轉出後會變成 &#nnnnn; 的格式

string big5_deunicode( string str) : 將字串網頁用的 Unicode 轉成 Big5 中文 , 也就是把 &#nnnnn; 格式的字串轉成一般中文字串

string big5_utf8_encode( string str) : BIG5 碼的字串轉為 UTF-8 格式的字串

string big5_utf8_decode( string str) : UTF-8 格式的字串轉為 BIG5 格式的字串

string big5_utf16_encode( string str) : BIG5 碼的字串轉為 UTF-16 格式的字串

string big5_utf16_decode( string str) : UTF-16 格式的字串轉為 BIG5 格式的字串


版本異動

0.23 版 (2005/1/20)
1. 判斷是否有 mb function , 若有 , 則某些函數的效能可以加快 , 為何不另外做一個 big5_func.mb.php ? 因為經過測試 , mb function 的轉碼 mb_convert_encoding() 在速度上比 iconv 速度慢太多 .. 所以不打算另外做一個全新的函數 , 而只挑幾個速度快的函數修改
2. 修改 big5_func.iconv.php 內的函數 , 採用 UTF-8 來轉碼 , 改變的原因不明 ... 不知道以前怎麼想的 ... 怎會用 UTF-16 轉來轉去又判斷一堆有的沒的 , 另外就是有網友討論 , ICONV 新版本在使用 big5_addslashes big5_stripslashes 出現錯誤而建議我改寫 , 因此就改成以 UTF-8 直接轉
0.22 版 (2003/3/6)
應網友 ADar Que 要求 , 增加 big5_strrpos 函數 , 與原 PHP 的 strrpos 用法一模一樣
修正 big5_strpos() 若指定 offset 則傳回數字會錯誤 , 謝謝 Adar Que 指正
增加一些函數的錯誤追蹤 , 方便撰寫程式時發生錯誤會顯示那一個函數,檔案,行數的錯誤

0.21 版 (2003/3/4)
修正 big5_substr() 當開始字串開始的位置為負數時會產生錯誤
取消 big5_func.inc 需要指定 BIG5_FILE_DIR 的位置

0.20 版 (2003/1/9)
修正 big5_deunicode() 的錯誤
感謝網友小葉([email protected])指正


0.19 版 (2003/1/7)
小幅修正 iconv 版的 big5_deunicode() , 稍微加快轉換速度 , 大概快5% ... 感覺不太出來 , 除非自己寫測速程式
改寫 iconv 版的 big5_addslashes() , 速度增加非常多 , 應該有加快 50% ~ 100% , 另外iconv 版的 big5_strtolower 與 big5_strtoupper 在處理長度較長的字串也有加快很多


0.18 版 (2002/12/01)
大幅修改所有字串處理函數充分使用到 iconv 來加速 , 並且新增 big5_func.default.php 與 big5_func.iconv.php , 當有裝 iconv 時將會以 big5_func.iconv.php 內的函數處理 , 也是方便維護啦 ..
大家最常用來解決中文字串的 big5_addslashes() 至少增加 6 成以上速度 , 若字串的字元數很多越能感受到差異 , 其他的函數也至少有 5 成以上的加速 , 當然前提是要安裝 iconv
另外 , 我在 iconv 轉換國際碼部分改成以 CP950 來轉 , 而不是 BIG5 , 因為大多數人使用的 Windows 都是 CP950 字集 , 他是 BIG5 的擴充 , 確實某些中文字或符號使用 iconv 以 BIG5 轉時會失效 , 因此才改成 CP950

0.17 版 (2002/11/29)
修正許多 Bug
1. Win32 版下 Cache 多國語言對應檔失效 , 已經修正 , 目前已經可正常在 WIN32 下執行
2. big5_deunicode 在沒有 iconv 下轉換失敗
3. 提升許多函數的效能大約5%的速度...真的有算過,HA HA
特別感謝 Neil Lin([email protected]) 閒閒沒事幹幫我測試

0.16 版 (2002/11/27)
有點想哭了 , 檢查很多函數發覺還是有 bug , 此次修正很多函數如下
big5_isBig5 : 改寫對於判斷是否為中文字的方式改變 , 特地去網路找到正確的編碼範圍 , 因此比較準確了
big5_chunk_split : 無 iconv 中英文混在一起時會有錯誤
big5_str_replace : 有 iconv 時會有問題
big5_utf16_encode 與 big5_utf16_decode : 英文轉碼錯誤
另外重新檢查過所有函數 , 也都有修改過 , 原來的函數多少都有加快運算速度了

0.15 版 (2002/11/26)
大幅修正轉多國語言碼或轉回 BI5 時呼叫太多次 big5_func 函數時效能低落的情形
修正原因 : 因為每次呼叫多國語言函數字碼的函數是每次呼叫每次要開檔讀檔 , 因此效能差
所以利用新增的物件 Big5FileCache 改成只開檔一次 , 相關函數對 Big5FileCache 讀取資料
但若 php 若安裝了 iconv , 則沒有效能的增進 ... 因為 iconv 夠快了
另外 , 不知道怎麼稿的 ... big5_unicode() 裡頭有個小錯誤 , 如果沒裝 iconv 不能轉...已經修正

0.14 版 (2002/11/22)
新增 big5_deunicode()

0.13 版 (2002/05/27)
新增 big5_utf16_encode() big5_utf16_decode()
並且嘗試使用 iconv 函數來加速字串處理(非常快)
如果沒有安裝 iconv 仍可以繼續使用 , 不必考慮前版程式相容問題
加速的函數有:
big5_utf8_encode() : 加快100倍以上
big5_utf8_decode() : 加快100倍以上
big5_unicode() : 加快100倍以上
big5_substr() : 當抓取的起始值由 200 開始或抓取字元數超過200才加速
big5_strlen() : 字串如果只有 10 字差 3 倍 , 100 字以後差了 10 倍以上了 ...
big5_strpos() : 此函數由big5_strlen與big5_substr組合寫成 , 連帶此函數也加速許多
big5_chunk_split() : 此函數由big5_strlen與big5_substr組合寫成 , 連帶此函數也加速許多
big5_str_replace() : 100 字的取代加快 50 倍以上,字串越長差異倍數越大

0.12 版 (2002/04/23)
修正 stripcslashes() , big5_unicode()
遇到\0, \a, \b, \f, \n, \r, \t \v 應該是要直接換成該對應的字
big5_unicode 誤刪了一些東西照成什麼都轉不出來 ... shit

0.11 版 (2002/04/22)
加 big5_addcslashes() 與 big5_stripcslashes()
作用與 addcslashes() 與 stripcslashes() 一樣 , 但是遇到中文字時則保留不轉換
另外 big5 轉 utf8 unicode 的效能再度提昇 , 對照表也有更改
測試 1 萬字轉 utf8 大約 0.8 秒以下 , 比前一版又快了 15%

0.10 版 (2002/04/21)
提昇 bi5 轉 utf8 , unicode , 效能再提升加快 2 倍
據我自己的電腦測試 , 測試 1 萬中文字轉 utf8 已經可以低於 1 秒了 ...
big5_substr() 重寫也加快了一點點速度

0.09 版 (2002/04/20)
修正許多函數寫法 , 提昇效能
據測試 : big5 轉 utf 與 big5 轉 unicode 提昇效能 0.08 版效能 10 倍以上
測試 1 萬 個中文字轉 utf8 大約需要 2.2 秒 , 比前一版(居然超過2分鐘快上非常多)
雖然還不是挺滿意 , 不過已經可以接受
另外 big5_substr , big5_strlen 改了一些寫法所有快了一點點 ...

0.08 版 (2002/04/19)
新增 big5_unicode($string) , big5_utf8_encode(),big5_utf8_decode(), 修改 big5_stroke($string)
big5_unicode() 可以將中文轉成多國語言給網頁用的碼
big5_utf8_encode() 可以將中文轉成 UTF8 碼
big5_utf8_decode() 可以將 UTF8 轉成 BIG5 碼
big5_stroke() 改成開檔方式 , 這樣不用到此函數時比較省記憶體

0.07 版 (2002/4/12)
新增 int big5_stroke($string)
此函數可計算單一中文字的筆劃 , 若輸入的不是中文則return false

0.06 版 (2002/2/22)
新增 big5_str_replace()
此函數用法與 str_replace() 一樣

0.05 版 (2002/2/13)
修正 big5_stripslashes()
此函數會把所有 "\" 去掉的問題 , 謝謝網友Neil指正

0.04 版 (2001/11/12)
把一些定義與判斷中文碼錯誤修正 , 感謝網友小藍 ...

0.03 版(2001/06/16)
新增函數 : string big5_strpos(string haystack ,string needle , int [offset]) : 傳回第一個找到字串的位置

0.02 版 (2001/05/28)
新增函數
string big5_chunk_split(string $str, [int $chunklen=76] , [string $end="\r\n"]) : 與 chunk_split 相同

0.01 版 (2001/05/27)
第一版 提供的函數
string big5_addslashes(string str) : 與 PHP addslashes 一樣的功能 , 可以處理中文
string big5_stripslashes(string str) : 與 stripslashes 一樣
int big5_strlen(string str) : 與 strlen 功能相同
string big5_substr(string str,int start , int length) : 與 substr 一樣
string big5_strtolower(string str) : 與 strtolower 一樣
string big5_strtoupper(string str) : 與 strtoupper 一樣

版權聲明
本程式完全免費 , 任何人都可以自由修改與善佈 , 但是若有修改本程式任何程式碼 , 請保留原始作者(就是我)的版權聲明
作者 Pigo Chu <[email protected]>

realmax
2005-06-13, 05:08 PM
我想台灣應該要放棄big-5編碼,
全面推廣unicode(utf-8)未來才能徹底解決衝碼問題

lenbo
2005-06-13, 09:19 PM
我想台灣應該要放棄big-5編碼,
全面推廣unicode(utf-8)未來才能徹底解決衝碼問題

嗯…
小弟也是覺得未來 unicode 才有前途
不過目前似乎只有 M$ 的 O$ 在支援說…
一般程式還是使用各自的語言編碼為大宗…

小弟之前上學校老師教的 JAVA 課
也是用 unicode 來達到多國語言程式說…

softbrian
2005-06-13, 09:33 PM
UNICODE +1


我也常常被一些衝碼問題搞的暈頭轉向....
BIG5也許有他的歷史意義吧 ,但也不是不能改. ..

最好是弄個全世界統一個編碼系統....大家不要再爭來爭去..世界大同

misol
2005-06-13, 10:39 PM
嗯…
不過目前似乎只有 M$ 的 O$ 在支援說…

Fedora Core 、 Redhat Enterprise Linux 已經全面支援 utf-8
跟 M$ 的相容度也不錯了
可以多多跟企鵝靠攏了 :D

ps
2005-06-14, 10:51 AM
Fedora Core 、 Redhat Enterprise Linux 已經全面支援 utf-8
跟 M$ 的相容度也不錯了
可以多多跟企鵝靠攏了 :D


請問一下 MS 和 Linux 的UTF-8有相容性問題嗎?