Как парсеры JSON кодируют символы Юникода не в базовой многоязычной плоскости? - PullRequest
0 голосов
/ 18 октября 2018

Я пишу парсер JSON в Xojo.Это работает помимо того факта, что я не могу понять, как кодировать и декодировать строки Unicode, которые не находятся в основной многоязычной плоскости (BMP).Другими словами, мой парсер умирает, если сталкивается с чем-то большим, чем \uFFFF.

Спецификации говорят:

Чтобы избежать кодовой точки, которая не находится в базовой многоязычной плоскости, символ может быть представлен в виде последовательности из двенадцати символов, кодирующей UTF-16суррогатная пара, соответствующая кодовой точке.Так, например, строка, содержащая только символ G clef (U + 1D11E), может быть представлена ​​как «\ uD834 \ uDD1E».Однако то, интерпретирует ли процессор текстов JSON такую ​​суррогатную пару как одну кодовую точку или как явную суррогатную пару, является семантическим решением, которое определяется конкретным процессором.

Что я не делаюпонять, каков алгоритм перехода от U+1D11E к \uD834\uDD1E.Я не могу найти никакого объяснения того, как «кодировать суррогатную пару UTF-16, соответствующую кодовой точке».

Например, скажем, я хочу кодировать символ смайлика (U+1F600).Что это будет за суррогатная пара UTF-16 и как она работает?

Может ли кто-нибудь, по крайней мере, указать мне правильное направление?

1 Ответ

0 голосов
/ 19 октября 2018

Взято из статьи в Википедии, на которую ссылается Реми Лебо в комментариях выше ( ссылка ):

Для кодирования U + 10437 (?) в UTF-16:

Вычтите 0x10000 из кодовой точки, оставив 0x0437.Для высокого суррогата сдвиньте вправо на 10 (разделите на 0x400), затем добавьте 0xD800, в результате чего 0x0001 + 0xD800 = 0xD801.Для низкого суррогата возьмите младшие 10 бит (остаток от деления на 0x400), затем добавьте 0xDC00, в результате чего 0x0037 + 0xDC00 = 0xDC37.Чтобы декодировать U + 10437 (?) из UTF-16:

Возьмите старший суррогат (0xD801) и вычтите 0xD800, затем умножьте на 0x400, в результате чего 0x0001 × 0x400 = 0x0400.Возьмите низкий суррогат (0xDC37) и вычтите 0xDC00, получив 0x37.Добавьте эти два результата вместе (0x0437) и, наконец, добавьте 0x10000, чтобы получить окончательно декодированную кодовую точку UTF-32, 0x10437.

...