你發現社群媒體市場在極短貼文這塊有個缺口。 既然 Twitter 現在允許 280 個字元的貼文,那些想要快速更新社群動態的人反而沒被服務到。 你決定打造自己的社群媒體網路。
為了讓你的產品與眾不同,你把它做到極端:只允許 5 個字元以內的貼文。 任何超過 5 個字元的貼文都應該截斷成 5 個字元。
為了讓使用者能充分表達自己,你允許 Emoji 和其他 Unicode 字元。
你的任務是把輸入字串截斷成 5 個字元。
以數位形式儲存的文字必須轉換成一連串的位元組。 目前常見的字元對應到位元組的方式有 3 種。
UTF-8 和 UTF-16 都是 Unicode 編碼,這表示它們能夠表示非常多種字元,包括:
UTF-8 和 UTF-16 都是可變長度編碼,這表示不同的字元佔用的空間大小也不同。
來看看字母「a」和 Emoji「😛」。 在 UTF-16 中,字母佔 2 位元組,但這個 Emoji 佔 4 位元組。
這道練習的訣竅,在於使用以 Unicode 字元(碼點)為核心設計的 API,而不是以 Unicode 碼元為核心的 API。
「一般」的 UTF-16 編碼字串可以表示成一連串字元,其中每個字元最長可達 16 位元(這也是 UTF-16 這個名稱的由來)。這代表以 16 位元(也就是 1 個編碼單元)最多可表示 2¹⁶(2 的十六次方),也就是 65536 種可能的字元。這 65536 個字元構成了所謂的基本多文種平面,它大到足以涵蓋大多數語言中最常見的字元。
不過,有些符號就是無法塞進單一個編碼單元。解決辦法是用兩個編碼單元來表示它們。這兩個 UTF-16 編碼單元(通常也稱為_代理對_)構成一個編碼點。
所以總結來說,講到 UTF-16 編碼時:
code unit 是代表單一字元的 16 位元(或更少)。code point 是代表單一字元的一或兩個編碼單元。更令人困惑的是,還有_字素叢集_,基本上就是應該被視為單一視覺單位的一連串 Unicode 字元(編碼點)。例如某些表情符號,像這個 👨👦。
大多數 Javascript 內建方法都能處理 UTF-16 編碼的字串,但它們是根據 UTF-16 編碼單元運作的。例如,String.prototype.split("") 方法會依編碼單元來切割字串。
另一方面,String iterators 則是依編碼點來疊代。
你可以在 MDN 上讀到更多內容,並找到關於 Unicode 字串的範例。