Юнико́д (чаще всего) или Унико́д (англ. Unicode) — стандарт кодирования символов, позволяющий представить знаки почти всех письменных языков.
Стандарт предложен в 1991 году некоммерческой организацией «Консорциум Юникода» (англ. Unicode Consortium, Unicode Inc.). Применение этого стандарта позволяет закодировать очень большое число символов из разных письменностей: в документах Unicode могут соседствовать китайские иероглифы, математические символы, буквы греческого алфавита, латиницы и кириллицы, при этом становится ненужным переключение кодовых страниц.
Стандарт состоит из двух основных разделов: универсальный набор символов (англ. UCS, universal character set) и семейство кодировок (англ. UTF, Unicode transformation format). Универсальный набор символов задаёт однозначное соответствие символов кодам — элементам кодового пространства, представляющим неотрицательные целые числа. Семейство кодировок определяет машинное представление последовательности кодов UCS.
Коды в стандарте Юникод разделены на несколько областей. Область с кодами от U+0000 до U+007F содержит символы набора ASCII с соответствующими кодами. Далее расположены области знаков различных письменностей, знаки пунктуации и технические символы. Часть кодов зарезервирована для использования в будущем. Под символы кириллицы выделены области знаков с кодами от U+0400 до U+052F, от U+2DE0 до U+2DFF, от U+A640 до U+A69F (см. Кириллица в Юникоде).
Хотя формы записи UTF-8 и UTF-32 позволяют кодировать до 231 (2 147 483 648) кодовых позиций, было принято решение использовать лишь 1 112 064 для совместимости с UTF-16. Впрочем, даже и этого на текущий момент более чем достаточно — в версии 6.0 используется чуть менее 110 000 кодовых позиций (109 242 графических и 273 прочих символов).
Кодовое пространство разбито на 17 плоскостей (англ. planes) по 216 (65 536) символов. Нулевая плоскость (англ. plane 0) называется базовой (англ. basic) и содержит символы наиболее употребительных письменностей. Остальные плоскости — дополнительные (англ. supplementary). Первая плоскость (англ. plane 1) используется, в основном, для исторических письменностей, вторая (англ. plane 2) — для редко используемых иероглифов китайского письма (ККЯ), третья (англ. plane 3) зарезервирована для архаичных китайских иероглифов. Плоскости 15 и 16 выделены для частного употребления.
Для обозначения символов Unicode используется запись вида «U+xxxx» (для кодов 0…FFFF), или «U+xxxxx» (для кодов 10000…FFFFF), или «U+xxxxxx» (для кодов 100000…10FFFF), где xxx — шестнадцатеричные цифры. Например, символ «я» (U+044F) имеет код 044F16 = 1103
Универсальная система кодирования (Юникод) представляет собой набор графических символов и способ их кодирования для компьютерной обработки текстовых данных.
Графические символы — это символы, имеющие видимое изображение. Графическим символам противопоставляются управляющие символы и символы форматирования.
Графические символы включают в себя следующие группы: буквы, содержащиеся хотя бы в одном из обслуживаемых алфавитов; цифры; знаки пунктуации; специальные знаки (математические, технические, идеограммы и пр.); разделители.
Юникод — это система для линейного представления текста. Символы, имеющие дополнительные над- или подстрочные элементы, могут быть представлены в виде построенной по определённым правилам последовательности кодов (составной вариант, composite character) или в виде единого символа (монолитный вариант, precomposed character). На данный момент (2014) считается, что все буквы крупных письменностей в Юникод внесены, и если символ доступен в составном варианте, дублировать его в монолитном виде не нужно.
Консорциум не создаёт нового, а констатирует сложившийся порядок вещей. Например, картинки «эмодзи» были добавлены потому, что японские операторы мобильной связи широко их использовали. Для этого добавление символа проходит через сложный процесс. И, например, символ рубля прошёл его за три месяца просто потому, что до этого шесть лет широко использовался.
Товарные знаки кодируют только в порядке исключения. Так, в Юникоде нет флага Windows или яблока Apple.
Как только символ появился в кодировке, он никогда не сдвинется и не исчезнет. Если же потребуется изменить порядок символов, это делается не переменой позиций, а национальным порядком сортировки. Есть и другие, более тонкие гарантии стабильности — например, не будут меняться таблицы нормализации
Один и тот же символ может иметь несколько форм; в Юникод эти формы входят одной кодовой позицией: если это сложилось исторически. Например, у арабских букв есть четыре формы: обособленная, в начале, в середине и в конце[34]; либо если в одном языке принята одна форма, а в другом — другая. Болгарская кириллица отличается от русской, а китайские иероглифы — от японских.
С другой стороны, если исторически в шрифтах были две разных кодовых позиции, они остаются разными и в Юникоде. Строчная греческая сигма имеет две формы, и они — разные позиции. А с кружком и знак ангстрема, греческое мю и латинское «микро-» — разные символы.
Конечно же, похожие символы в неродственных письменностях ставятся в разные кодовые позиции. Например, буква «А» в латинице, кириллице, греческом и чероки — разные символы.
Крайне редко один и тот же символ ставится в две разные кодовые позиции для упрощения обработки текста. Математический штрих и такой же штрих для индикации мягкости звуков — разные символы, второй считается буквой.
Графические символы в Юникоде подразделяются на протяжённые и непротяжённые (бесширинные). Непротяжённые символы при отображении не занимают места в строке. К ним относятся, в частности, знаки ударения и прочие диакритические знаки. Как протяжённые, так и непротяжённые символы имеют собственные коды. Протяжённые символы иначе называются базовыми (англ. base characters), а непротяжённые — модифицирующими (англ. combining characters); причём последние не могут встречаться самостоятельно. Например, символ «á» может быть представлен как последовательность базового символа «a» (U+0061) и модифицирующего символа « ́» (U+0301) или как монолитный символ «á» (U+00C1).
Особый тип модифицирующих символов — селекторы варианта начертания (англ. variation selectors). Они действуют только на те символы, для которых такие варианты определены. В версии 5.0 варианты начертания определены для ряда математических символов, для символов традиционного монгольского алфавита и для символов монгольского квадратного письма.
Поскольку одни и те же символы можно представить различными кодами, сравнение строк байт за байтом становится невозможным. Алгоритмы нормализации (англ. normalization forms) решают эту проблему, выполняя приведение текста к определённому стандартному виду. Приведение осуществляется путём замены символов на эквивалентные с использованием таблиц и правил. «Декомпозицией» называется замена (разложение) одного символа на несколько составляющих символов, а «композицией», наоборот, — замена (соединение) нескольких составляющих символов на один символ.
В стандарте Юникода определены 4 алгоритма нормализации текста: NFD, NFC, NFKD и NFKC.
NFD, англ. normalization form D («D» от англ. decomposition), форма нормализации D — каноническая декомпозиция — алгоритм, согласно которому выполняется рекурсивная замена монолитных символов (англ. precomposed characters) на несколько составных (англ. composite characters) в соответствии с таблицами декомпозиции.
NFC, англ. normalization form C («C» от англ. composition), форма нормализации C — алгоритм, согласно которому последовательно выполняются каноническая декомпозиция и каноническая композиция. Сначала каноническая декомпозиция (алгоритм NFD) приводит текст к форме D. Затем каноническая композиция — операция, обратная NFD, обрабатывает текст от начала к концу с учётом следующих правил: символ S считается начальным, если имеет класс модификации равный нулю согласно таблице символов Юникода; в любой последовательности символов, начинающейся с символа S, символ C блокируется от S, только если между S и C есть какой-либо символ B, который либо является начальным, либо имеет одинаковый или больший класс модификации, чем C. Это правило распространяется только на строки, прошедшие каноническую декомпозицию; символ считается первичным композитом, если имеет каноническую декомпозицию в таблице символов Юникода (или каноническую декомпозицию для хангыля и он не входит в список исключений); символ X может быть первично совмещён с символом Y, если и только если существует первичный композит Z, канонически эквивалентный последовательности <X, Y>; если очередной символ C не блокируется последним встреченным начальным базовым символом L и он может быть успешно первично совмещён с ним, то L заменяется на композит L-C, а C удаляется.
NFC, англ. normalization form C («C» от англ. composition), форма нормализации C — алгоритм, согласно которому последовательно выполняются каноническая декомпозиция и каноническая композиция. Сначала каноническая декомпозиция (алгоритм NFD) приводит текст к форме D. Затем каноническая композиция — операция, обратная NFD, обрабатывает текст от начала к концу с учётом следующих правил: символ S считается начальным, если имеет класс модификации равный нулю согласно таблице символов Юникода; в любой последовательности символов, начинающейся с символа S, символ C блокируется от S, только если между S и C есть какой-либо символ B, который либо является начальным, либо имеет одинаковый или больший класс модификации, чем C. Это правило распространяется только на строки, прошедшие каноническую декомпозицию; символ считается первичным композитом, если имеет каноническую декомпозицию в таблице символов Юникода (или каноническую декомпозицию для хангыля и он не входит в список исключений); символ X может быть первично совмещён с символом Y, если и только если существует первичный композит Z, канонически эквивалентный последовательности <X, Y>; если очередной символ C не блокируется последним встреченным начальным базовым символом L и он может быть успешно первично совмещён с ним, то L заменяется на композит L-C, а C удаляется.
NFKD, англ. normalization form KD, форма нормализации KD — совместимая декомпозиция — алгоритм, согласно которому последовательно выполняются каноническая декомпозиция и замены символов текста по таблицам совместимой декомпозиции. Таблицы совместимой декомпозиции предусматривают замену на почти эквивалентные символов: похожих на буквы (ℍ и ℌ); обведённых кружками (①); с изменёнными размерами (カ и カ); повёрнутых (︷ и {); степеней (⁹ и ₉); дробей (¼); других (™).
Стандарт Юникод поддерживает письменности языков как с направлением написания слева направо (англ. left-to-right, LTR), так и с написанием справа налево (англ. right-to-left, RTL) — например, арабское и еврейское письмо. В обоих случаях символы хранятся в «естественном» порядке; их отображение с учётом нужного направления письма обеспечивается приложением.
Кроме того, Юникод поддерживает комбинированные тексты, сочетающие фрагменты с разным направлением письма. Данная возможность называется двунаправленность (англ. bidirectional text, BiDi). Некоторые упрощённые обработчики текста (например, в сотовых телефонах) могут поддерживать Юникод, но не иметь поддержки двунаправленности. Все символы Юникода поделены на несколько категорий: пишущиеся слева направо, пишущиеся справа налево, и пишущиеся в любом направлении. Символы последней категории (в основном это знаки пунктуации) при отображении принимают направление окружающего их текста.
Юникод имеет несколько форм представления (англ. Unicode transformation format, UTF): UTF-8, UTF-16 (UTF-16BE, UTF-16LE) и UTF-32 (UTF-32BE, UTF-32LE). Была разработана также форма представления UTF-7 для передачи по семибитным каналам, но из-за несовместимости с ASCII она не получила распространения и не включена в стандарт. 1 апреля 2005 года были предложены две шуточные формы представления: UTF-9 и UTF-18 (RFC 4042).
В Microsoft Windows NT и основанных на ней системах Windows 2000 и Windows XP в основном используется форма UTF-16LE. В UNIX-подобных операционных системах GNU/Linux, BSD и Mac OS X принята форма UTF-8 для файлов и UTF-32 или UTF-8 для обработки символов в оперативной памяти.
Punycode — другая форма кодирования последовательностей Unicode-символов в так называемые ACE-последовательности, которые состоят только из алфавитно-цифровых символов, как это разрешено в доменных именах.
Внедрение Юникода привело к изменению подхода к традиционным 8-битным кодировкам. Если раньше кодировка задавалась шрифтом, то теперь она задаётся таблицей соответствия между данной кодировкой и Юникодом. Фактически 8-битные кодировки превратились в форму представления некоторого подмножества Юникода. Это намного упростило создание программ, которые должны работать с множеством разных кодировок: теперь, чтобы добавить поддержку ещё одной кодировки, надо всего лишь добавить ещё одну таблицу перекодировки в Юникод.
Кроме того, многие форматы данных позволяют вставлять любые символы Юникода, даже если документ записан в старой 8-битной кодировке. Например, в HTML можно использовать коды с амперсандом.
Большинство современных операционных систем в той или иной степени обеспечивают поддержку Юникода.
В операционных системах семейства Windows NT для внутреннего представления имён файлов и других системных строк используется двухбайтовая кодировка UTF-16LE. Системные вызовы, принимающие строковые параметры, существуют в однобайтном и двухбайтном вариантах. Подробнее см. в статье Юникод в операционных системах Microsoft.
UNIX-подобные операционные системы, в том числе GNU/Linux, BSD, Mac OS X, используют для представления Юникода кодировку UTF-8. Большинство программ могут работать с UTF-8 как с традиционными однобайтными кодировками, не обращая внимания на то, что символ представляется как несколько последовательных байт. Для работы с отдельными символами строки обычно перекодируются в UCS-4, так что каждому символу соответствует машинное слово.
Одной из первых успешных коммерческих реализаций Юникода стала среда программирования Java. В ней принципиально отказались от 8-битного представления символов в пользу 16-битного. Это решение увеличивало расход памяти, но позволило вернуть в программирование важную абстракцию: произвольный одиночный символ (тип char). В частности, программист мог работать со строкой, как с простым массивом. К сожалению, успех не был окончательным, Юникод перерос ограничение в 16 бит и к версии J2SE 5.0 произвольный символ снова стал занимать переменное число единиц памяти — один char или два (см. суррогатная пара).
Сейчас большинство языков программирования поддерживают строки Юникода, хотя их представление может различаться в зависимости от реализации.
Поскольку ни одна раскладка клавиатуры не может позволить вводить все символы Юникода одновременно, от операционных систем и прикладных программ требуется поддержка альтернативных методов ввода произвольных символов Юникода.
В Юникоде английское «a» и польское «a» — один и тот же символ. Точно так же одним символом (но отличающимся от «a» латинского) считаются русское «а» и сербское «а». Такой принцип кодирования не универсален; по-видимому, решения «на все случаи жизни» вообще не может существовать. Тексты на китайском, корейском и японском языках имеют традиционное написание сверху вниз, начиная с правого верхнего угла. Переключение горизонтального и вертикального написания для этих языков не предусмотрено в Юникоде — это должно осуществляться средствами языков разметки или внутренними механизмами текстовых процессоров. Юникод предусматривает возможность разных начертаний одного и того же символа в зависимости от языка. Так, китайские иероглифы могут иметь разные начертания в китайском, японском (кандзи) и корейском (ханча), но при этом в Юникоде обозначаются одним и тем же символом (так называемая CJK-унификация), хотя упрощённые и полные иероглифы всё же имеют разные коды. Аналогично, русский и сербский языки используют разное начертание курсивных букв п и т (в сербском они выглядят как и и ш, см. сербский курсив). Поэтому нужно следить, чтобы текст всегда был правильно помечен как относящийся к тому или другому языку. Перевод из строчных букв в заглавные тоже зависит от языка. Например: в турецком существуют буквы İi и Iı — таким образом, турецкие правила изменения регистра конфликтуют с английскими, которые предписывают «i» переводить в «I». Подобные проблемы есть и в других языках — например, в канадском диалекте французского языка регистр переводится немного не так, как во Франции. Даже с арабскими цифрами есть определённые типографские тонкости: цифры бывают «прописными» и «строчными», пропорциональными и моноширинными — для Юникода разницы между ними нет. Подобные нюансы остаются за программным обеспечением.
Некоторые недостатки связаны не с самим Юникодом, а с возможностями обработчиков текста. Файлы неанглийского текста в Юникоде всегда занимают больше места, так как один символ кодируется не одним байтом, как в различных национальных кодировках, а последовательностью байтов (исключение составляет UTF-8 для языков, алфавит которых укладывается в ASCII, а также наличие в тексте символов двух и более языков, алфавит которых не укладывается в ASCII). Файл шрифта, необходимый для отображения всех символов таблицы Юникод, занимает сравнительно много места в памяти и требует бо́льших вычислительных ресурсов, чем шрифт только одного национального языка пользователя. С увеличением мощности компьютерных систем и удешевлением памяти и дискового пространства эта проблема становится всё менее существенной; тем не менее, она остаётся актуальной для портативных устройств, например, для мобильного телефона. Хотя поддержка Юникода реализована в наиболее распространённых операционных системах, до сих пор не всё прикладное программное обеспечение поддерживает корректную работу с ним. В частности, не всегда обрабатываются метки порядка байтов (BOM) и плохо поддерживаются диакритические символы. Проблема является временной и есть следствие сравнительной новизны стандартов Юникода (в сравнении с однобайтовыми национальными кодировками). Производительность всех программ обработки строк (в том числе и сортировок в БД) снижается при использовании Юникода вместо однобайтовых кодировок.
Некоторые редкие системы письма всё ещё не представлены должным образом в Юникоде. Изображение «длинных» надстрочных символов, простирающихся над несколькими буквами, как, например, в церковнославянском языке, пока не реализовано.