Douglas Crockford




2020 Appearances





How JavaScript Works


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, contributing the least significant 7 bits. This gives up the sorting property of UTF-8 in exchange for greater simplicity and performance.

of bytes
Codepoint range
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 a first byte if the preceding byte has a top bit of zero.

Kim can also be used to represent block lengths, large integers, and other transmission values. Applications that require negative numbers may use a leading 0x80 to represent the minus sign. A leading 0x80 must not be immediately followed by another 0x80 or by 0x00.

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