UTF-16 и суррогатные пары
Коротко: UTF-16 хранит символы Unicode в 16-битных единицах. Символы за пределами первых 65 536 требуют двух единиц — суррогатной пары.
Подробнее: Java, JavaScript, C# и Windows внутренне используют UTF-16. Поэтому длина строки там часто не равна числу видимых символов.
Подробности
- Базовая плоскость (BMP): Кодовые точки U+0000–U+FFFF занимают одну единицу.
- Суррогатная пара: Кодовая точка от U+10000 (многие эмодзи) разбивается на старшую (D800–DBFF) и младшую единицу (DC00–DFFF).
- Следствие:
"😀".lengthв JavaScript равно 2. Если разрезать посреди пары, получится недопустимый символ.Array.from(s)илиfor…ofработают по кодовым точкам. - Порядок байтов: UTF-16LE и UTF-16BE, часто с BOM (byte order mark) в начале файла.
- В сравнении с UTF-8: UTF-8 совместим с ASCII и является стандартом веба. UTF-16 почти ничего не экономит для большинства текстов CJK.
- Ещё тоньше: Один видимый символ может состоять из нескольких кодовых точек (кластеры графем, например флаги или эмодзи с оттенком кожи).
См. также: UTF-8 и кодировка символов