Skip to content
Tech News
← Back to articles

Show HN: Mojibake – a low-level Unicode library written in C

read original more articles
Why This Matters

Mojibake is a lightweight, high-performance Unicode processing library written in C that simplifies text normalization, case folding, and character counting across multiple platforms. Its compatibility with C++17 and minimal setup make it an attractive tool for developers needing reliable Unicode support. This development enhances the robustness and interoperability of text handling in software, benefiting both industry applications and end-users dealing with internationalized content.

Key Takeaways

Mojibake is a low-level Unicode 17 text-processing library written in C11 and compatible with C++17. It is released under the MIT License.

Usage

You don't need to install anything. There are two files ( mojibake.c , mojibake.h ) to add to your C/C++ project. Download it here mojibake-amalgamation-027.zip

Examples of normalization, characters count and NFKC casefold.

void print_string ( const char *input, size_t length) ; int main ( int argc, char * const argv[]) { const char *input = "Cafe\xCC\x81" ; size_t length = strlen (input); mjb_result result; if (mjb_normalize(input, length, MJB_ENC_UTF_8, MJB_NORMALIZATION_NFC, MJB_ENC_UTF_8, &result) != MJB_STATUS_OK) { return 1 ; } print_string(input, length); print_string(result.output, result.output_size); const char *mojibake = "文字化け" ; length = strlen (mojibake); printf ( "\"%s\" encoded in UTF-8 is %zu bytes long, and %zu characters long

" , mojibake, length, mjb_string_length(mojibake, length, MJB_ENC_UTF_8)); mjb_result_free(&result); const char *case_input = "Straße" ; if (mjb_nfkc_casefold(case_input, strlen (case_input), MJB_ENC_UTF_8, MJB_ENC_UTF_8, &result) != MJB_STATUS_OK) { return 1 ; } printf ( "%s -> %.*s

" , case_input, ( int )result.output_size, result.output); mjb_result_free(&result); return 0 ; } void print_string ( const char *input, size_t length) { for ( size_t i = 0 ; i < length; ++i) { unsigned char byte = ( unsigned char )input[i]; if (byte >= 0x21 && byte <= 0x7E ) { printf ( "%c" , byte); } else { printf ( "<%02X>" , byte); } } printf ( "

" ); }

This output:

Cafe<CC><81> Caf<C3><A9> "文字化け" encoded in UTF-8 is 12 bytes long, and 4 characters long Straße -> strasse

... continue reading