Douglas Crockford

Blog

Books

Videos

2019 Appearances

JavaScript

JSLint

JSON

Github

How JavaScript Works

About

UTF-8 and Kim

Unicode is a 21 bit character set. Its 21-ness seems like an odd choice, resulting from a long series of unintended consequences stretching back to the design of ASCII. There are three popular conventions for how to represent Unicode:

UTF-8 was designed by Ken Thompson. It has some very nice properties:

UTF-8 has some disadvantages. It is a little complicated in encoding and decoding. It represents ASCII very efficiently, but for all of the other characters, it only delivers about 5 bits per byte. UTF-8 can have aliases where a character can be encoded multiple ways, requiring additional rules and policies. This is an attractive nuisance; some systems intentionally violate the rules.

I propose another representation for the wire called Kim. Kim is a very simple encoding that delivers 7 bits per byte. The bottom 7 bits of each byte contain data, which can be accumulated to produce 21 bit characters. The top bit of each byte is 1 if the byte is not the last byte of a character. The top bit of each byte is 0 if the byte is the last byte of a character. This gives up the sorting property of UTF-8 in exchange for greater simplicity and performance. The antialiasing rule requires that the first byte of a character can not be 0x80.

Kim can also be used to represent block lengths and other transmission values.

Number
of bytes
Codepoint range
KimUTF-8
1U+007FU+007F
2U+3FFFU+07FF
3U+10FFFF U+FFFF
4 U+10FFFF

Characters in the ranges U+0800 thru U+3FFF and U+10000 thru U+10FFFF will be one byte smaller when encoded in Kim compared to UTF-8.

Kim is beneficial when using scripts such as Aramaic, Avestan, Balinese, Batak, Bopomofo, Buginese, Buhid, Carian, Cherokee, Coptic, Cyrillic, Deseret, Egyptian Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Hangul Jamo, Hanunoo, Hiragana, Kanbun, Kaithi, Kannada, Katakana, Kharoshthi, Khmer, Lao, Lepcha, Limbu, Lycian, Lydian, Malayalam, Mandaic, Meroitic, Miao, Mongolian, Myanmar, New Tai Lue, Ol Chiki, Old South Arabian, Old Turkic, Oriya, Osmanya, Pahlavi, Parthian, Phags-Pa, Phoenician, Samaritan, Sharada, Sinhala, Sora Sompeng, Tagalog, Tagbanwa, Takri, Tai Le, Tai Tham, Tamil, Telugu, Thai, Tibetan, Tifinagh, and Unified Canadian Aboriginal Syllabics.

As with UTF-8, it is possible to detect character boundaries within a byte sequence. A byte is the first byte if the preceding byte has a top bit of zero.

UTF-8 is one of the world's great inventions. While Kim is more efficient, it is not clear that it is worth the expense of transition.