Как рассчитываются суррогатные пары? - PullRequest
1 голос
/ 15 января 2012

Если юникод использует 17-битные кодовые точки, как суррогатные пары вычисляются из кодовых точек?

Ответы [ 2 ]

7 голосов
/ 15 января 2012

Кодовые точки Unicode - это скалярные значения в диапазоне от 0x000000 до 0x10FFFF.Таким образом, они представляют собой 21-разрядные целые числа, а не 17-разрядные.

Суррогатные пары представляют собой механизм формы UTF-16.Это представляет 21-битные скалярные значения в виде одной или двух 16-битных единиц кода.

  • Скалярные значения от 0x000000 до 0x00FFFF представлены в виде одной 16-битной кодовой единицы, от 0x0000 до 0xFFFF.
  • Скалярные значения от 0x00D800 до 0x00DFFF не являются символами в Unicode, и поэтому они никогда не появятся в строке символов Unicode.
  • Скалярные значения от 0x010000 до 0x10FFFF представлены в виде двух 16-битных кодовединицы.Первая кодовая единица кодирует старшие 11 бит скалярного значения в виде кодовой единицы в диапазоне от 0xD800-0xDBFF.Есть небольшая хитрость, чтобы закодировать значения от 0x01-0x10 в четыре бита.Вторая кодовая единица кодирует младшие 10 бит скалярного значения в виде кодовой единицы в диапазоне от 0xDC00-0xDFFF.

Это подробно объясняется с помощью примера кода в часто задаваемых вопросах консорциума Unicode, UTF-8, UTF-16, UTF-32 & BOM .Этот FAQ относится к разделу стандарта Unicode, в котором есть еще больше деталей.

4 голосов
/ 15 января 2012

Если вам нужен код, вот как кодируется одна кодовая точка в UTF-16 и UTF-8 соответственно.

Одна кодовая точка для кодовых блоков UTF-16:

if (cp < 0x10000u)
{
   *out++ = static_cast<uint16_t>(cp);
}
else
{
   *out++ = static_cast<uint16_t>(0xd800u + (((cp - 0x10000u) >> 10) & 0x3ffu));
   *out++ = static_cast<uint16_t>(0xdc00u + ((cp - 0x10000u) & 0x3ffu));
}

Одна кодовая точка для кодовых блоков UTF-8:

if (cp < 0x80u)
{
   *out++ = static_cast<uint8_t>(cp);
}
else if (cp < 0x800u)
{
   *out++ = static_cast<uint8_t>((cp >> 6) & 0x1fu | 0xc0u);
   *out++ = static_cast<uint8_t>((cp & 0x3fu) | 0x80u);
}
else if (cp < 0x10000u)
{
   *out++ = static_cast<uint8_t>((cp >> 12) & 0x0fu | 0xe0u);
   *out++ = static_cast<uint8_t>(((cp >> 6) & 0x3fu) | 0x80u);
   *out++ = static_cast<uint8_t>((cp & 0x3fu) | 0x80u);
}
else
{
   *out++ = static_cast<uint8_t>((cp >> 18) & 0x07u | 0xf0u);
   *out++ = static_cast<uint8_t>(((cp >> 12) & 0x3fu) | 0x80u);
   *out++ = static_cast<uint8_t>(((cp >> 6) & 0x3fu) | 0x80u);
   *out++ = static_cast<uint8_t>((cp & 0x3fu) | 0x80u);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...