Mojibake 0.2.7 – 零相依 Unicode 17 函式庫(適用於 C11/C++17)
Mojibake 0.2.7 – 零相依 Unicode 17 函式庫(適用於 C11/C++17)
Mojibake 0.2.7 在單一檔案 C 函式庫中提供完整的 Unicode 17 支援
Mojibake 0.2.7 實作了整個 Unicode 17.0.0 規範——包括正規化、大小寫折疊、分段、雙向排版、表情符號處理、排序與安全檢查——且 不需要任何外部相依,也不需要執行時期支援。這使得它非常適合無法負擔龐大函式庫的低階專案。
為何零相依的 Unicode 函式庫很重要
大多數 C/C++ 專案都依賴大型第三方 Unicode 函式庫(例如 ICU),會拉入龐大的程式碼基礎、複雜的建置系統與執行時資料表。Mojibake 透過將所有原始碼與 Unicode 資料表合併成兩個檔案(mojibake.c 與 mojibake.h)繞過了這些問題。最終得到一個 單一標頭/實作檔,只要把它放入任何專案、使用任意 C11 或 C++17 編譯器編譯,即可在不額外連結其他函式庫的情況下使用。
主要功能一覽
| 功能 | API 函式 | 標準參考 |
|---|---|---|
| 正規化(NFC、NFD、NFKC、NFKD) | mjb_normalize, mjb_string_is_normalized |
UAX #15 |
| 大小寫折疊與轉換(大寫、 小寫、 標題、 NFKC casefold) | mjb_case, mjb_nfkc_casefold |
UAX #31, UAX #15 |
| 分段(字形叢集、單詞、句子、換行) | mjb_break_grapheme_cluster, mjb_break_word, mjb_break_sentence, mjb_break_line |
UAX #29, UAX #14 |
| 雙向演算法(段落解析、行重新排序) | mjb_bidi_resolve, mjb_bidi_reorder_line |
UAX #9 |
| 表情符號分析(屬性、序列偵測、RGI 檢查) | mjb_string_emoji_sequence, mjb_string_is_rgi_emoji |
UTS #51 |
| 排序(UCA 比較、排序鍵產生) | mjb_string_compare, mjb_collation_key |
UTS #10 |
| 安全性(混淆字偵測、識別字驗證) | mjb_confusable_skeleton, mjb_string_is_confusable, mjb_string_is_identifier |
UTS #39, UAX #31 |
| 編碼轉換(UTF‑8、UTF‑16LE/BE、UTF‑32LE/BE) | mjb_string_convert_encoding, mjb_string_encoding |
— |
| 顯示寬度與截斷(終端欄位、寬度感知截斷) | mjb_display_width, mjb_truncate_width |
UAX #11 |
所有函式皆回傳詳細的 mjb_status 列舉,讓呼叫端能區分成功、參數無效、記憶體失敗與溢位等情況。
最小化整合步驟
- 下載合併檔 –
mojibake-amalgamation-027.zip內含mojibake.c與mojibake.h。 - 將檔案加入 專案的原始碼樹。
- 在需要 Unicode 處理的地方 包含標頭檔:
#include "mojibake.h" - 使用任意 C11 或 C++17 編譯器編譯;不需要額外的連結旗標。
因為函式庫 沒有執行時期需求,你也可以將它嵌入靜態函式庫、韌體或 WebAssembly 模組,而不必再拉入其他二進位檔。
效能考量(社群問題)
"它和 utf8proc 比較如何?" – @lifthrasiir
Mojibake 提供的功能比 utf8proc 更廣(後者僅聚焦於 UTF‑8 驗證、正規化與大小寫折疊)。它額外支援完整的雙向處理、Unicode 排序、表情符號序列偵測與安全導向的混淆字檢查。作者尚未公布基準數據,直接的速度比較仍屬傳聞。
"與 Python 的 ftfy 模組相比效能如何?" – @tjwebbnorfolk
ftfy 是高階的 Python 函式庫,會對錯誤的 Unicode 進行大量自動修正。Mojibake 在較低層級提供原始演算法,並不自動修復錯誤。因此純粹的吞吐量可能較高,但原始碼中並未提供並排基準。
用於尺寸受限環境的建置時功能切換
Mojibake 允許在編譯時排除可選資料表以縮減二進位大小。例如,關閉字元名稱可減少約 30 % 的資料佔用:
# CMake
cmake -S . -B build-no-name -DMJB_FEATURE_CHARACTER_NAMES=OFF
cmake --build build-no-name
# Makefile 快捷方式
make build BUILD_DIR=build-no-name FEATURE_CHARACTER_NAMES=OFF
其他資料表(如表情符號屬性、腳本擴充)亦可透過 MJB_FEATURE_* 巨集以相同方式裁減。
安全導向的工具
- 混淆字偵測 –
mjb_confusable_skeleton產生語言無關的骨架;mjb_string_is_confusable比較兩個字串的視覺相似度,以防止同形攻擊。 - 識別字驗證 –
mjb_string_is_identifier強制執行 Unicode 識別字規則(ID_Start/ID_Continue 或 XID 變體),適用於編譯器與直譯器。
兩項工具皆依賴官方 Unicode 安全資料檔(confusables.txt、IdentifierStatus.txt)。
測試、模糊測試與相容性保證
Mojibake 依官方 Unicode 測試套件驗證所有支援的演算法。專案使用 Attractor 測試框架執行 150 萬+ 斷言,包括:
- 完整的 Unicode 正規化測試向量。
- 雙向演算法相容性。
- 排序測試資料。
- 表情符號序列驗證。
此外,函式庫持續以 libFuzzer 進行模糊測試,所有建置皆在 AddressSanitizer 與 UBSan 下執行,以捕捉記憶體安全問題。
社群回響(精選 HN 評論)
"喜歡這種合併檔方式——C/C++ 生態真的需要更乾淨、輕量的 Unicode 支援,而不必拉入龐大相依…感謝分享" – @digg99
此評論突顯單檔函式庫對於無法承受重量級相依的專案的實用價值。
"我得出結論,C 語言唯一需要的 Unicode 支援就是支援 char 指標與陣列,但輕量的 C 函式庫永遠受歡迎" – @avadodin
提醒即使是最基本的 Unicode 處理(例如正確的長度計算、大小寫折疊)也往往需要超越純位元組陣列的功能;Mojibake 正好填補了這個缺口。
"不是挑毛病,但‘mojibake’這個詞不就是‘字元編碼破碎’的同義詞嗎?" – @CharlesW
函式庫名稱刻意呼應文字亂碼的經典問題,同時提供防止此類問題的工具。
授權與法律聲明
Mojibake 以 MIT License 發布。它包含 Unicode Character Database 與 CLDR 資料,這些資料保留原始的 Unicode 授權(請參閱 license.txt 與 CLDR LICENSE)。
快速上手
- 下載 最新發行版(v0.2.7)自 GitHub releases 頁面。
- 閱讀 API 參考(
API.md)以取得詳細函式簽名。 - 執行 CLI(
src/shell/mojibake)進行快速實驗,例如:mojibake nfc $'Cafe\u0301' # → NFC: Café mojibake emoji "☺️" # → 顯示表情符號分類 - 貢獻 – 參見
CONTRIBUTING.md了解加入新 Unicode 版本或修正錯誤的指引。
結論
Mojibake 0.2.7 以極小、零相依的套件提供 完整、符合標準的 Unicode 17 實作。其單檔發佈、豐富功能與徹底測試,使其成為任何需要可靠 Unicode 處理、卻不想承擔大型函式庫負擔的 C 或 C++ 專案的理想選擇。