1. Что такое Unicode?
Unicode возникла из очень простой идеи: включить всех персонажей в мире в коллекцию. Пока компьютер поддерживает этот набор символов, он может отображать все символы, и снова не будет искаженного кода.
Он начинается с 0 и определяет число для каждого символа, который называется «CodePoint». Например, символ кодовой точки 0 является нулевым (указывает, что все бинарные биты 0).
Скопируйте код следующим образом: U+0000 = NULL
В вышеупомянутой формуле U+ означает, что шестнадцатеричное число сразу же следующее приведено кодовая точка Unicode.
В настоящее время последняя версия Unicode - версия 7.0, в общей сложности 109 449 символов, из которых 74 500 включены в китайские, японские и корейские персонажи. Можно примерно поверить, что более двух третей существующих символов в мире поступают от восточной азиатской персонажей. Например, кодовая точка для китайского «хорошего» - шестнадцатеричный 597d.
Скопируйте код следующим образом: U+597D = OK
С таким большим количеством символов Unicode определяется не один раз, а определение раздела. Каждая область может хранить 65 536 (216) символов, называемых плоскостью. В настоящее время существует всего 17 (25) плоскостей, что означает, что размер всего набора символов Unicode в настоящее время составляет 221.
Первые 65536 битов символов называются основной плоскостью (сокращенно BMP), а их кодовые точки варьируются от 0 до 216-1. Написано в Hexadecimal от U+0000 до U+FFFF. Все наиболее распространенные символы размещены в этой плоскости, которая является первой плоскостью, которую Unicode определяет и публикует.
Остальные символы помещаются в вспомогательную плоскость (сокращенную SMP), а точки кода варьируются от U+010000 до U+10FFFF.
2. UTF-32 и UTF-8
Unicode указывает только код точки каждого символа. Какой заряд байтов используется для представления этой кодовой точки, которая включает в себя метод кодирования.
Наиболее интуитивно понятным методом кодирования является то, что каждая кодовая точка представлена четырьмя байтами, а содержание байта соответствует кодовой точке один за другим. Этот метод кодирования называется UTF-32. Например, кодовая точка 0 представлена четырьмя байтами 0, а кодовая точка 597D добавляется с двумя байтами 0 впереди.
Скопируйте код следующим образом: U+0000 = 0x0000 0000U+597d = 0x0000 597d
Преимущество UTF-32 заключается в том, что правила конверсии просты и интуитивно понятны, а эффективность поиска высока. Недостаток заключается в том, что он потрачен впустую, а английский текст с тем же контентом будет в четыре раза больше, чем кодирование ASCII. Этот недостаток является фатальным, что не приводит к тому, что никто не использует этот метод кодирования. Стандарт HTML5 явно предусматривает, что веб-страницы не должны быть закодированы в UTF-32.
Людям действительно нужен метод экономии космического обеспечения, который привел к рождению UTF-8. UTF-8 является методом кодирования с переменной длиной, с длиной символов в диапазоне от 1 до 4 байтов. Более часто используемые символы, тем короче байтов. Первые 128 символов представлены только 1 байтом, что точно так же, как код ASCII.
Диапазон номеров Bytes 0x0000 - 0x007f10x0080 - 0x07ff20x0800 - 0xfff30x010000 - 0x10ffff4
Из-за функции экономии пространства UTF-8 она стала наиболее распространенным веб-кодированием в Интернете. Тем не менее, это имеет мало общего с сегодняшней темой, поэтому я не буду вдаваться в это. Для конкретного метода транскодирования, пожалуйста, обратитесь к «Примечаниям кодирования персонажа», которые я написал много лет назад.
Iii. Введение в UTF-16
Кодирование UTF-16 находится между UTF-32 и UTF-8, и сочетает в себе характеристики двух методов кодирования: фиксированная длина и переменная длина.
Его правила кодирования просты: символы в базовой плоскости занимают 2 байта, а символы в вспомогательной плоскости занимают 4 байта. То есть длина кодирования UTF-16 составляет либо 2 байта (U+0000 до U+FFFF), либо 4 байта (U+010000 до U+10FFFF).
Итак, есть вопрос: когда мы сталкиваемся с двумя байтами, как мы видим, что это сам персонаж, или нам нужно интерпретировать его с двумя другими байтами?
Это очень умно, и я не знаю, было ли это намеренно. В основной плоскости от U+D800 до U+DFFF является пустым сегментом, то есть эти кодовые точки не соответствуют каким -либо символам. Следовательно, этот пустой сегмент можно использовать для картирования символов вспомогательной плоскости.
В частности, в вспомогательной плоскости есть 220 битов, что означает, что для этих символов требуется не менее 20 двоичных битов. UTF-16 расщепляет эти 20 бит пополам. Первые 10 бит отображаются в U+D800 до U+DBFF (размер пространства 210), который называется высоким битом (H), а последние 10 битов отображаются в U+DC00 - U+DFFF (размер пространства 210), который называется низким битом (L). Это означает, что характер вспомогательной плоскости разбит на две основные плоскости представлений символов.
Поэтому, когда мы сталкиваемся с двумя байтами и обнаруживаем, что его кодовая точка находится между U+D800 и U+DBFF, мы можем сделать вывод, что кодовая точка сразу же после двух байтов должна находиться между U+DC00 и U+DFFF. Эти четыре байта должны интерпретироваться вместе.
IV Формула транскодирования UTF-16
При преобразовании точек кода Unicode в UTF-16 сначала отличите, является ли это основным плоским символом или вспомогательным плоским символом. Если это первое, напрямую преобразуйте кодовую точку в соответствующую шестнадцатеричную форму с длиной двух байтов.
Скопируйте код следующим образом: u+597d = 0x597d
Если это вспомогательный плоский символ, Unicode версия 3.0 дает формулу транскодирования.
Скопируйте код кода следующим образом: h = math.floor ((C -0x10000) / 0x400) + 0xd800l = (c - 0x10000) % 0x400 + 0xdc00
Принимая персонаж в качестве примера, это вспомогательный символ плоскости с кодовой точкой U+1D306. Процесс расчета преобразования его в UTF-16 выглядит следующим образом.
Скопируйте код кода следующим образом: h = math.floor ((0x1d306-0x10000)/0x400)+0xd800 = 0xd834l = (0x1d306-0x10000) % 0x400+0xdc00 = 0xdf06
Следовательно, кодирование персонажа UTF-16 составляет 0xd834 DF06, с длиной четыре байта.
5. Какая кодировка используется в JavaScript?
Язык JavaScript использует наборы символов Unicode, но поддерживает только один метод кодирования.
Это кодирование не является не UTF-16, ни UTF-8, ни UTF-32. JavaScript не использует приведенные выше методы кодирования.
JavaScript использует UCS-2!
VI Кодирование UCS-2
Почему внезапно появился UCS-2? Это требует небольшой истории.
В эпоху, когда Интернет еще не появился, были две команды, которые оба хотели создать унифицированный набор персонажей. Одним из них является команда Unicode, созданную в 1988 году, а другой является команда UCS, созданная в 1989 году. Когда они обнаружили существование друг друга, они быстро достигли соглашения: в мире нет необходимости в двух объединенных наборах персонажей.
В октябре 1991 года две команды решили объединить набор персонажей. Другими словами, с этого момента будет выпущен только один набор наборов символов, который является Unicode, а ранее выпущенные наборы символов будут пересмотрены, а кодовые точки UC будут точно такими же, как Unicode.
Прогресс развития UCS быстрее, чем Unicode. В 1990 году был объявлен первый метод кодирования UCS-2, используя 2 байта для представления символов с кодовыми точками. (В то время была только одна плоскость, которая была основной плоскостью, поэтому 2 байта было достаточно.) Кодирование UTF-16 не было объявлено до июля 1996 года, и было ясно объявлено, что это был суперсет UCS-2, то есть основной символы плоскости были кодированы UCS-2, а символы вспомогательного плоскости определили метод 4-бей.
Проще говоря, связь между ними заключается в том, что UTF-16 заменяет UCS-2 или UCS-2 интегрирована в UTF-16. Итак, теперь есть только UTF-16, нет UCS-2.
7. Фон рождения JavaScript
Итак, почему JavaScript не выбирает более продвинутый UTF-16, но использует уже устаревший UCS-2?
Ответ очень прост: это не то, что вы не хотите, это то, что вы не можете. Потому что, когда появился язык JavaScript, не было никакого кодирования UTF-16.
В мае 1995 года Брендан Эйх разработал язык JavaScript за 10 дней; В октябре был выпущен первый двигатель объяснений; В ноябре следующего года Netscape официально представил языковые стандарты ECMA (см. «Рождение JavaScript» для получения подробной информации обо всем процессе). Сравнивая дату выпуска UTF-16 (июль 1996 г.), вы поймете, что у Netscape не было другого выбора в то время, был доступен только метод кодирования UCS-2!
8. Ограничения функций символов JavaScript
Поскольку JavaScript может обрабатывать только кодирование UCS-2, все символы составляют 2 байта на этом языке. Если это 4 байта, они будут рассматриваться как два двойных байта. Функции символов JavaScript влияют на это и не могут вернуть правильный результат.
Возьмите персонажей в качестве примера, его кодирование UTF-16 составляет 4 байта 0xd834df06. Проблема заключается в том, что кодирование 4 байтов не принадлежит UCS-2, и JavaScript не распознает его и будет рассматривать его только как два отдельных символа U+D834 и U+DF06. Как упоминалось ранее, эти две кодовые точки пусты, поэтому JavaScript считает их строками, состоящими из двух пустых символов!
Приведенный выше код указывает на то, что JavaScript считает, что длина символа составляет 2, первым полученным символом является нулевым символом, а точка кода первого полученного символа составляет 0xdb34. Эти результаты не верны!
Чтобы решить эту проблему, вы должны судить о кодовой точке, а затем вручную настраивать ее. Ниже приведен правильный способ написать строку.
Скопируйте код кода следующим образом: while (++ index <length) {// ... if (charcode> = 0xd800 && charcode <= 0xdbff) {output.push (символ+string.charat (++ index)); } else {output.push (символ); }}
Приведенный выше код указывает на то, что при переселении строки вы должны вынести суждение о точке кода. Пока он попадает в интервал между 0xd800 и 0xdbff, его нужно прочитать вместе со следующими 2 байтами.
Подобные проблемы существуют во всех функциях манипуляции с символом JavaScript.
String.prototype.replace ()
String.prototype.substring ()
String.prototype.slice ()
...
Все вышеперечисленные функции действительны только для 2-байтовых кодовых точек. Чтобы правильно обработать 4-байтовые точки кода, вы должны развернуть свою собственную версию один за другим и оценить диапазон кодовых точек текущего символа.
9. Ecmascript 6
Следующая версия JavaScript, Ecmascript 6 (ES6 для короткого), имеет значительно повышенную поддержку Unicode, в основном решение этой проблемы.
(1) Правильно идентифицировать символы
ES6 может автоматически распознавать 4-байтовые кодовые точки. Следовательно, гораздо легче пересечь строки.
Скопируйте код следующим образом: for (let s string) {// ...}
Однако для поддержания совместимости атрибут длины по -прежнему остается исходным поведением. Чтобы получить правильную длину строки, вы можете использовать следующий метод.
Скопируйте код следующим образом: array.from (string) .length
(2) Представление точки кода
JavaScript позволяет символам Unicode быть представленными непосредственно с кодовыми точками, которые написаны как «BackSlash + U + Code Points».
Скопируйте код следующим образом: 'ok' === '/u597d' // true
Тем не менее, эта нотация недействительна для 4-байтовых кодовых точек. ES6 исправил эту проблему и мог правильно идентифицировать ее до тех пор, пока кодовые точки помещаются в кудрявые скобки.
(3) Функция обработки строки
ES6 добавил несколько новых функций, которые специально касаются 4-байтовых кодовых точек.
String.fromcodepoint (): вернуть соответствующий символ из точки кода Unicode
String.prototype.codepointat (): вернуть соответствующую кодовую точку из символа
String.prototype.at (): возвращает символ в заданном положении строки
(4) Регулярное выражение
ES6 предоставляет модификатор U, чтобы добавить 4-байтовые точки кода к регулярным выражениям.
(5) регуляризация Unicode
У некоторых персонажей есть дополнительные символы в дополнение к буквам. Например, в китайском пиньине тон на букве является дополнительным символом. Символы тона очень важны для многих европейских языков.
Unicode предоставляет два метода представления. Одним из них является единственный символ с дополнительными символами, то есть кодовая точка представляет собой символ, такой как кодовая точка ǒ U+01D1; Другой состоит в том, чтобы использовать дополнительный символ в качестве кодовой точки и отобразить его в сочетании с основным героем, то есть две кодовые точки представляют собой символ, такой как ǒ, можно записать как O (U+004F)+ˇ (U+030C).
Скопируйте код следующим образом: // Метод 1 '/u01d1' // 'ǒ' // Метод 2 '/u004f/u030c' // 'ǒ'
Эти два метода представления точно одинаковы в зрения и семантики и должны рассматриваться как эквивалентные ситуации. Однако JavaScript не может сказать.
Скопируйте код следующим образом: '/u01d1' === '/u004f/u030c' // false
ES6 предоставляет метод нормализуемости, позволяющий «регуляризации Unicode», то есть преобразование двух методов в одну и ту же последовательность.
Скопируйте код следующим образом: '/u01d1'.normalize () ===' /u004f/u030c'.normalize () // true
Для получения дополнительной информации о ES6, см. «Развлечение Ecmascript 6».