< 返回

《Unicode String長度點計你真係知?》



作者:IT9
日期:2018年2月6日

睇下一條String有幾長 可以用咩法?
IT9你玩我下嘛 length吖嘛
三歲細路仔都識啦
真係?你真係識?
等我哋開個Javascript console睇下
恭喜發財 length
4個字吖嘛 都話三歲細路仔都識㗎啦
吓?講呢啲?
1 2 3 4 5 一隻手都數得哂
咪5囉 5個字囉
哈 真係要講呢啲?
有分別咩 咪又係一樣
哈?點解係6個字㗎
點解會係6個字㗎
到底點解會係噉㗎

回帶到1993年 Unicode 1.1定稿嘅時候
只係定義咗三萬四千幾隻字
三萬四千幾隻字
喺二進制要用幾多個bit先至可以表達到呢?
答案就係16個Bit
而絕大部份嘅電腦都係以8-bit為1個Byte嘅
並且以1個byte為最細嘅定址單位
噉16 bit啱啱好兩個byte順住排
都可以表達到65536個組合啦
用咗喺三萬四千幾隻字之後
都仲有三萬幾個士啤空間 綽綽有餘啦
噉所以就制定咗UCS-2呢種編碼方式
固定梗死用兩個byte 去表示所有Unicode嘅字符
當然喺1993年 大部份嘅使用者都係用英文
而英文加數字加埋符號
加埋都係得嗰百幾個字
其實7個bit 又或者1個byte就裝得哂
當大部份嘅文字數據都係用英文嘅時候
如果要轉哂做UCS-2嘅編碼其實好浪費空間
所以呢 就制定咗另外一隻UTF-8嘅可變長度編碼方式
一般英文用1個byte就夠表達
到要表示其他語言嘅字嘅時候呢
先至用返兩或者3個byte

Windows、Java甚乎至之後嘅Javascript
都揀咗用UCS-2作為內部保存string嘅編碼方法
喺UCS-2編碼底下 要知道條string有幾長?
好簡單啫 因為梗死一個字兩個byte
所以將條string佔用嘅byte數 除以2
就知道答案喇

Unicode 1.1達到咗佢最初嘅目的
就係將所有當時電腦可以表達嘅字
都收哂落統一嘅編碼裏面
各個歐州語言 中日韓 等等
都可以用統一嘅編碼表示 真係皆大歡喜呀
然之後科學家就有一個更高更大嘅目標
就係務求將古今中外嘅字都收哂落Unicode標準裏面
但係我哋打開本康熙字典睇一睇呀
裏面就已經有成四萬九咁多隻字 哈哈
可想言之呀 UCS-2所只能夠表達到65536個字符
其實真係唔係好夠用

到咗1996年 Unicode 2.0就確立咗新嘅字符上限
由原本0到65535個 提升到百幾萬個
UCS-2被退役 更新成為UTF-16編碼方法
UTF-16去表達第0到第65535嗰啲隻字嘅時候
都係同UCS-2一樣 都係用嗰兩個byte
但去到表達第65536去到百幾萬嗰啲字嘅時候呢
就要用4個byte喇
UCS-2本來係固定長度 去到UTF-16嘅時候呢
就變咗做可變長度嘅編碼方法
而當呢啲系統升級嘅時候
佢嘅length嘅function 因為有各種原因呢
都係要keep返做係byte除以2嘅計算方法

噉所以當要表達呢一個字
又或者呢一個Emoji嘅時候
佢哋都係2000年之後先至編入去Unicode嘅字
用UTF-16表示法呢 其實就佔用咗4個byte
所以length得出來呢 就係會等於2喇

長度陷阱只有一個?
少年 你太年輕喇
我哋睇一睇呢個歐洲字符嘅字
length係1
又睇一睇呢一個
length竟然係2
但係佢哋兩個真係同一個字
無論你放到幾大去睇都好
都係同一隻字
噉今次又咩嘢事呢?

Unicode係有一種組合嘅機制
例如好多西歐語言都用到嘅重音符號
都可以用呢啲組合嘅方法去表達
2017年所定嘅Unicode 10 裏面嘅Emoji規格
更加係將呢個玩法發揮到極致呀
例如呢度咁多個Emoji
係會合得埋出咗一隻字
Unicode喺制定嘅時候

為咗方便可以從舊嘅編碼標準
過渡到呢個新嘅Unicode標準
所以喺表達呢一個字嘅時候
都可以用返另外一個已經組合嘅版本
兩個版本喺顯示上面呢都係同一個字
但係背後嘅儲存內容就唔一樣
需要嘅時候 就要用返Unicode Normalization嘅方法
將佢哋轉換成NFC又或者NFD嘅編碼方式喇

講到尾想知條string有幾長
就要睇下你用來做咩啦
如果係要放喺database裏面
有空間嘅長度限制㗎話呢
就應該先用咗一啲編碼方法 再數下有幾多個byte
如果係為限制一個顯示嘅長度嘅話呢
就應該用你最後嘅字型render咗出來
再度下有幾長喇

嘩真係數個string有幾長 都原來咁鬼複雜
係咪真係覺得 撳個Like
同埋撳個Subscribe掣 簡單好多呢
即刻試下撳下個Mouse Click一Click
好簡單㗎咋 簡單十幾倍呀

全文 1227 字 (唔計英文、空格、標點)