在一個Encoding為BIG5的網頁有以下的Code,你覺得結果會是多少?
<script language=vbscript>
S=”中文123”
MsgBox LenB(S)
</script>

依照LenB的定義,S字串的Big5位元組數應為7,多年來我也一直這樣以為。實際跑過,你會發現它的結果是10!! 也就是123也被視為Double Bytes。


在藍色小舖有篇文章證實了這一點,但文中提到的FN_Len函數已經失傳了,所以我試著自己動手寫了一個(希望夠嚴謹,發現有問題的人再回報給我),大家可以參考看看:


'取代LENB傳回BIG5字串的正確位元組數
Function GetBytesCount(S) 

    Dim I,C,A

    C=0

    For I=1 To Len(S)

       A=ASC(Mid(S,I,1)) '*見以下更新說明

       C=C+1

       '如果是ASC 0-255,表示為Single Byte

       '否則為Double Byte,算雙位元組

       If (A>255 OR A<0) THEN C=C+1

    Next

    GetBytesCount=C

End Function


如果要用ASP或VBScript組裝固定欄位長度的字串時,要特別留意這個陷阱!

【Update 2007-09-29 】
謝謝網友Vincent的回應,ASC()在識別Big5不支援的Unicode難字時,會傳回63(?),因此造成誤判把Unicode難字的長度視為1;而用ASCW()則Unicode難字則可順利傳回非0-255的值,判定長度為2。不過有個弔詭的問題來了,如果這段文字被轉純Big5 Encoding時,難字會變成問號"?",此時長度還真的是1呢!
因此要用ASC或ASCW,端賴你後續將字串轉成Byte Array時,如何詮釋Unicode難字而定。如果難字會變問號的,請用ASC;如果可以用Big5E或造字機制將難字轉成Double-Byte的,則可改用ASCW。


Comments

# by vincent

您好: 試用您的function時, 發現若遇到unicode的字會判斷成1 後來試著把Asc() 改為 AscW 就可以了, 供您參考

# by Jeffrey

To Vincent, 厲害,我沒想到這個問題。 不過用ASCW似乎有好有壞,請參見我文章裡的更新說明。

Post a comment