В UTF-16 символы вне BMP представлены с использованием суррогатной пары с первой кодовой единицей (CU) лежит между 0xD800—0xDBFF, а вторая между 0xDC00 -0xDFFF. Каждый из CU представляет 10 битов кодовой точки. Символы в BMP кодируются как сам.
Теперь синхронизация проста. Учитывая положение любой произвольной кодовой единицы:
- Если кодовая единица находится в диапазоне 0xD800—0xDBFF, это первая кодовая единица из двух, просто прочитайте следующую и декодируйте. Вуаля, у нас есть полный характер за пределами BMP
- Если кодовая единица находится в диапазоне 0xDC00—0xDFFF, это вторая кодовая единица из двух, просто вернитесь на одну единицу, чтобы прочитать первую часть, или перейдите к следующей единице, чтобы пропустить текущий символ
- Если он не входит ни в один из этих диапазонов, то это персонаж в BMP. Нам не нужно больше ничего делать
В UTF-16 CU - это единица измерения, то есть наименьший элемент. Мы работаем на уровне CU и читаем CU один за другим, а не побайтно. Из-за этого, наряду с историческими причинами, UTF-16 самосинхронизируется только на уровне CU
Смысл самосинхронизации состоит в том, чтобы узнать, находимся ли мы в середине чего-то сразу, вместо того, чтобы снова читать с самого начала и проверять. UTF-16 позволяет нам делать это
Поскольку диапазоны для верхних суррогатов, нижних суррогатов и действительных символов BMP равны дизъюнктам , суррогат не может соответствовать символу BMP или для (частей) двух соседних символов выглядеть как законная суррогатная пара. Это значительно упрощает поиск. Это также означает, что UTF-16 имеет самосинхронизирующийся для 16-разрядных слов: можно ли определить, начинается ли кодовая единица символ, без проверки более ранних кодовых единиц. UTF-8 разделяет эти преимущества, но многие более ранние схемы многобайтового кодирования (такие как Shift JIS и другие азиатские многобайтовые кодировки) не допускали однозначного поиска и могли синхронизироваться только путем повторного анализа из начало строки (UTF-16 не является самосинхронизирующимся, если один байт потерян или если обход начинается со случайного байта).
https://en.wikipedia.org/wiki/UTF-16#Description
Конечно, это означает, что UTF-16 может не подходить для работы над средой без исправления / обнаружения ошибок, например, в «голой» сетевой среде. Однако в надлежащей локальной среде это намного лучше, чем работать без самосинхронизации. Например, в DOS / V для японского языка каждый раз, когда вы нажимаете Backspace , вы должны выполнить итерацию с самого начала, чтобы узнать, какой символ был удален, потому что в ужасной кодировке Shift-JIS нет способа узнать как долго символ перед курсором находится без карты длины