2010年3月24日 星期三

Outlook 亂碼問題

Outlook 亂碼問題-轉自微軟MVP璉璉的部落格

話說在論壇常常看到有人問到收到郵件亂碼,這個亂碼問題要配圖檔比較好說明。

說明之前先說,因為搞太多了,所以我自己有很多寄信收信的小工具,也可以當成是郵件軟體,以一個郵件軟體開發者的角度來說這件事,不要當成這是經驗談或偏方,有時在論壇上就有人要用經驗跟我揮,乾脆叫對方貼出信頭還比較快。

電子郵件從寄件者電腦郵件軟體輸出成專用的 MIME 郵件後,一路使用 SMTP 遞送,經過寄件伺服器 [> 叢集可能還會有對外主站] > 收件伺服器 [> 叢集可能還會有對內分站] 保留在收件伺服器上。

收件者再以郵件軟體使用 POP3 到收件伺服器上下傳接收。

註:中括號表示可有可無

每經過一台 SMTP 轉送,包含收件伺服器分站,就會在信件最上方加上經過伺服器的記錄,所以若要追蹤各伺服器的時間、路徑,就可以從信頭來看,越上方的越後經過,越靠近收信者。

當然倒回推的時候,若是中間不是經過大型可信賴的郵件伺服器,可能會被偽造,比如說有些大企業內部可能有多個 Mail Server ,可能路徑是:

部門 Mail Server > 公司 Mail Server > 轉信站 (ISP 業者) ...

而一般使用者可能直接透過 ISP 業者寄出,所以一般使用者若知道某些大企業的信頭 (Mail Header) 找出路徑時,就可以仿造透過程式方式送出不存在的 Mail 記錄,佯裝是部門 Mail Server 寄出。

所以信頭很多不可靠,但是反過來說,一封郵件能不能正確的解讀,就要看信頭。

下面這張圖是一封信頭的結構圖,這是屬於 MIME 格式,詳情可參考 RFC1521 ,這種格式可以內崁,也就是一封郵件裡面可能還有多封郵件或檔案,比如說附加檔就是以 MIME 格式崁入在信件的 MIME 格式中。

而一封郵件是否能正確解碼,就看郵件是否有崁入編碼。

早期郵件通常是本國寄來寄去,但隨著國際化,跨國郵件越來越多,所以編碼的問題也越加重要,但這類軟體多半是英語系國家開發,所以包含 Outlook Express / Windows Live Mail / Outlook 的預設值,都是不寫入國際編碼資訊,而收信時若信頭沒有標記國際編碼時,就會依據控制台地區語言來假定這封郵件的編碼,當寄件者使用多國語言時,就容易發生亂碼。

最簡單的方法,就是請寄件者在 Outlook 外寄郵件編碼中,設定為 utf8 ,這邊不是指單封郵件的編碼,而是整套軟體的設定。整套軟體的設定會套用在整封郵件上,信件的編碼只會套用在 Mail Body 上,並不會影響到 Mail Header ,也就是說整封郵件的 MIME 編碼方式可以與內崁的附件採用不同的編碼方式,比如說你內文要用簡中,但你不需要把 Outlook 的設定變更為簡中,只需要把該封郵件的編碼變更為簡中即可。

特別的狀況:

假設簡中寄件者沒設定外寄的郵件編碼,會以 GB 編碼寄出,這個編碼相容 ANSI ,繁中收件者用 ANSI 相容的 Big5 就會解出一堆亂碼,但若使用者有安裝 Unicode 補完計畫,就會因為 ANSI 轉 big5 映射到 Unicode 後,顯示出部分正確的編碼,不過要注意,這只是剛剛好,不是通解。

正確的方法簡中寄件者發出郵件經過 Unicode 適用於網路傳輸的 utf8 邊碼寄送,到了使用者電腦就會用 utf8 解整封郵件,再依據內崁的內容顯示出簡體中文。

注意的部分:

Win9x(95/98/SE/Me) 是 ANSI Windows ,WinNT(2k/XP/2003/Vista/2008/7) 是 Unicode Windows ,Outlook 2002 以前是 ANSI Windows (所以才能安裝在 WinMe 以前) ,Outlook 2003 以後是 Unicode Windows ,只有 Outlook 2003 與 Windows 2000 以後才是純 Unicode 環境,能把亂碼問題減少到最少,此外若碰到掉字,可能是對方使用到 Unicode 3.1 以後的字元,Win2k/XP/2003 是 Unicode 2.0 ,WinVista/2008/7 是 Unicode 5.0 ,若使用到 Unicode 5.0 的字元,在舊版的環境下會無法顯示,哪些是 Unicode 3.1/5.0 的字元呢?先前這篇有,新注音輸入法中不是黑色的都是:

[測試記錄] UTF32 位元組數與 Char 型別~

剛剛測了一下 Unicode 5.0 裡面的字,如下圖:

黑字:Unicode 2.0 (常用字), 2 bytes

綠字:Unicode 3.1 (Ext.) ,2 bytes

紅字:Unicode 5.0, 4 bytes

紅字轉成 Char 後就怪怪的,因為 Char 是用 2 bytes 的整數,目前看 Char 這部分的說明看不太懂,寫的很模糊,先做個記錄。以後再測資料庫。

這是一個轉成 16 進位的簡表:

字元
UTF8
Unicode (UTF16)
UTF32


E4B880
004E
004E0000


E3BEA8
A83F
A83F0000


F0A3B2AB
4FD8ABDC
AB3C0200

測試圖:(點圖可放大)


沒有留言:

張貼留言