程式者的胡言亂語
java.net.URLDecoder的bug
我的關鍵詞雲一直都有點怪怪的:
怎麼會有個香花呢?我猜測那應該是丁香花。查了一下,原來是從百度這個搜尋引擎來的一個查詢,它查詢的字元編碼是Big5,但我卻解出了一個亂碼字元加上「香花」,這可怪了,我可是利用java.net.URLDecoder去解碼的,怎麼會出錯呢?而且其他的情況都正確,除了這個例子外,我還發現了其他幾個亂碼的例子。真是怪事,因為大多數的情況都正確。我追蹤了來自百度的那個查詢例子,它的查詢是這樣子的:
%A4B%AD%BB%AA%E1
通常由於URL中可以出現的字元有限,為了避掉一些不該出現的字元,Java的程式員常會利用java.net.URLEncoder來將某字串編碼,編碼後的結果會將不必要出現的字元轉換成另一種形式,通常會用%XX的形式來呈現。%XX就代表該字元的十六進位碼。我們利用java.net.URLDecoder可以將它解回(這裡其實還存在另一個問題,就是要用什麼encoding把它解回,不過不是本文的重點)。而上面列出的這個例子,在一堆%XX的形式中,出現了一個B,它並不是十六進位的形式。百度告訴我這串字是Big5,所以它是兩個位元組組成一個中文字,而丁的Big5碼,第一個byte是0xA4,第二個byte是0x42,由於0x42是URL中可以出現的字元,也就是B,所以百度傳來的URL並沒有加以編碼,第一個字「丁」,也就變成了%A4B。但是java.net.URLDecoder在收到這串字時,雖然知道它是Big5,但是由於看到第二個字元是B,就沒有把它和第一個%A4看成同一個中文字,所以我就看到爛掉的「丁」,因為java.net.URLDecoder把它變成兩個字元了。不論如何,這算bug吧!解決之道有二:第一,自己前處理那段字,把B換成0x42;第二,使用Jakarta Apache Commons下的Codec專案,其中的URLCodec提供了解碼的功能。不過怪的是我手上的Codec版本,好像還有另一個bug-_-。在它的constructor中指定charset,是沒有作用的,得呼叫可以傳入charset的decode()才會正確運作。
所以現在我有新版的關鍵詞雲啦:
「丁香花」一詞變大了。
Posted at 10:24下午 九月 12, 2006 by Chien-Hsing Wang in Java | 迴響[1]
星期二 九月 12, 2006

在最後一個關鍵詞雲中看到「三國演義裡的危機處理」、「六个人的小世界」、「食物熱量換算程式」這三個例子,可見你大概沒做斷詞吧,還是說是因為它們整組出現的頻率很高,高到你的演算法決定不予以拆解?
由...發表 william on 九月 13, 2006 at 11:42 上午 CST #