Что такое юникод и как им пользоваться
Юникод в вебе: введение для начинающих
Верите вы или нет, но существует формат изображений, встроенных в браузер. Этот формат позволяет загружать изображения до того, как они понадобились, обеспечивает рендеринг изображения на обычных или retina экранах и позволяет добавлять к изображениям CSS. ОК, это не совсем правда. Это не формат изображения, хотя все остальное остается в силе. Используя его, вы можете создавать иконки, независимые от разрешения, не требующие время на загрузку и стилизуемые с помощью CSS.
Что такое Юникод?
Юникод это возможность корректно отображать буквы и знаки пунктуации из различных языков на одной страницы. Он невероятно полезен: пользователи смогут работать с вашим сайтом по всему миру и он будет показывать то, что вы хотите — это может быть французский язык с диакритическими знаками или Kanji.
Юникод продолжает развиваться: сейчас актуальна версия 8.0 в которой более 120 тысяч символов (в оригинальной статье, опубликованной в начале 2014 года, речь шла о версии 6.3 и 110 тысячах символов).
Кроме букв и цифр, в Юникоде есть и другие символы и иконки. В последних версиях в их число вошли эмодзи, которые вы можете видеть в месседжере iOS.
Страницы HTML создаются из последовательности символов Юникода и при отсылке по сети они конвертируются в байты. Каждая буква и каждый символ любого языка имеют свой уникальный код и кодируются при сохранении файла.
При использовании системы кодирования UTF-8 вы можете напрямую вставлять в текст символы Юникода, но также можно добавлять их в текст, указывая цифровую символьную ссылку. Например, ♥ это символ сердечка и вы можете вывести этот символ, просто добавив код в разметку ♥.
Если вы добавляете символ Юникода с помощью CSS, то вы можете использовать только шестнадцатеричные значения.
Некоторые наиболее часто используемые символы Юникода имеют более запоминаемые текстовые имена или аббревиатуры вместо цифровых кодов — это, например, амперсанд ( & — &). Такие символы называются мнемоники в HTML, их полный список есть в Википедии.
Почему вам стоит использовать Юникод?
Хороший вопрос, вот несколько причин:
Корректные символы
Первая из причин не требует никаких дополнительных действий. Если HTML сохранен в формате UTF-8 и его кодировка передана по сети как UTF-8, все должно работать как надо.
Должно. К сожалению, не все браузеры и устройства поддерживают все символы Юникода одинаково (точнее, не все шрифты поддерживают полный набор символов). Например, недавно добавленные символы эмодзи поддерживаются не везде.
Для поддержки UTF-8 в HTML5 добавьте (при отсутствии доступа к настройкам сервера стоит добавить также ). При старом доктайпе используется ( ).
Иконки
Вторая причина использования Юникода это наличие большого количества полезных символов, которые можно использовать в качестве иконок. Например, ▶, ≡ и ♥.
Их очевидный плюс в том, что вам не надо никаких дополнительных файлов, чтобы добавить их на страницу, а, значит, ваш сайт будет быстрее. Вы также можете изменить их цвет или добавить тень с помощью CSS. А добавив переходы (css transition) вы сможете плавно менять цвет иконки при наведении на нее без каких-либо дополнительных изображений.
Предположим, что я хочу подключить индикатор рейтинга со звездами на свою страницу. Я могу сделать это так:
Получится следующий результат:
Образец рейтинга в Firefox
Но если вам не повезет, вы увидите что-то вроде этого:
Тот же рейтинг на BlackBerry 9000
Так бывает, если используемые символы отсутствуют в шрифте браузера или устройства (к счастью, эти звездочки поддерживаются отлично и старые телефоны BlackBerry являются здесь единственным исключением).
Если символ Юникода отсутствует, на его месте могут быть разные символы от пустого квадрата (□) до ромба со знаком вопроса (�).
А как найти символ Юникода, который может подойти для использования в вашем дизайне? Вы можете поискать его на сайте типа Unicodinator, просматривая имеющиеся символы, но есть и лучший вариант. Shapecatcher — этот отличный сайт позволяет вам нарисовать искомую иконку, после чего предлагает вам список похожих символов Юникода.
Использование Юникода с @font-face иконками
Слева иконки Font Awesome в Chrome, а справа замещающие их символы Юникода в Opera Mini.
Многие инструменты для подбора @font-face используют диапазон символов Юникода из области для частного использования (private use area). Проблема этого подхода в том, что если @font-face не поддерживается, пользователю передаются коды символов без какого-либо смысла.
Использование символов из области для частного использования может также вынудить Internet Explorer 8 перейти в режим совместимости, а это сродни открытию портала в ад и призванию отвратительных монстров из старых IE (подробнее эта проблема описана в статье Джереми Кита).
IcoMoon отлично подходит для создания наборов иконок в @font-face и позволяет выбрать в качестве основы для иконки подходящий символ Юникода.
Поддержка символов Юникода
Основная проблема с использованием символов Юникода в качестве запасного варианта это плохая поддержка в скринридерах (опять-таки, некоторые сведения об этом можно найти на Unify), поэтому важно осторожно выбирать используемые символы.
Если ваша иконка это просто декоративный элемент рядом с текстовой меткой, читаемым скринридером, вы можете особо не волноваться. Но если иконка расположена отдельно, стоит добавить скрытую текстовую метку, чтобы помочь пользователям скринридеров. Даже если символ Юникода будет считан скринридером, есть вероятность, что он будет сильно отличен от своего предназначения. Например, ≡ (≡) в качестве иконки-гамбургера будет считан VoiceOver на iOS как “идентичный”.
Юникод в названиях CSS-классов
То, что Юникод можно использовать в названиях классов и в таблицах стилей известно с 2007 года. Именно тогда Джонатан Снук написал об использовании символов Юникода во вспомогательных классов при верстке скругленных углов. Особого распространения эта идея не получила, но о возможности использовать Юникод в названиях классов (спецсимволы или кириллицу) знать стоит.
Выбор шрифтов
Совсем немногие шрифты поддерживают полный набор символов Юникода, поэтому при выборе шрифта сразу проверяйте наличие нужных вам символов.
Определение поддержки Юникода
Было бы очень удобно иметь возможность проверить наличие того или иного символа Юникода, но нет гарантированного способа сделать это.
В Modernizr есть проверка поддержки эмодзи — но она работает проверкой одного пикселя и поэтому даст неправильный результат, если в нужном символе этот пиксель не используется. Да и сама проверка наличия отдельного символа не скажет ничего о поддержке остальных ста тысяч.
Проверяйте. И обеспечивайте запасные варианты, чтобы пользователь всегда мог понять, что происходит при отсутствии нужного символа.
Юникод в письмах
Юникод можно использовать не только на веб-страницах, но и в письмах.
Но здесь есть та же проблема: некоторые почтовые клиенты и некоторые устройства поддерживают нужные символы, а некоторые нет. Небольшое тестирование, позволяющее определить уровень поддержки символов, было проведено Campaign Monitor.
Символы Юникода могут быть эффективны при наличии поддержки. Например, эмодзи в теме письма выделяет его на фоне остальных в почтовом ящике.
Заключение
Эта статья затрагивает лишь основы Юникода. Надеюсь, она окажется полезной и поможет вам лучше понять Юникод и эффективно применять его.
Что такое кодировки?
Компьютеры постоянно работают с текстами: это ленты новостных сайтов, фондовые биржи, сообщения в социальных сетях и мессенджерах, банковские приложения и многое другое. Сегодня мы не можем представить жизнь без передачи информации. Но так было не всегда. Компьютеры научились работать с текстом благодаря появлению кодировок. Кодировки прошли большой путь от таблиц символов, созданных отдельно для каждого компьютера, до единой кодировки, принятой во всём мире.
Сейчас Unicode — это основной стандарт кодирования символов, включающий в себя знаки почти всех письменных языков мира. Unicode применяется везде, где есть текст. Информация на страницах в социальных сетях, записи в базах данных, компьютерные программы и мобильные приложения — всё это работает с использованием Unicode.
В этом гайде мы рассмотрим, как появился Unicode и какие проблемы он решает. Узнаем, как хранилась и передавалась информация до введения единого стандарта кодирования символов, а также рассмотрим примеры кодировок, основанных на Unicode.
Предпосылки появления кодировок
Исторически компьютер создавался как машина для ускорения и автоматизации вычислений. Само слово computer с английского можно перевести как вычислитель, а в 20 веке в СССР, до распространения термина компьютер, использовалась аббревиатура ЭВМ — электронно вычислительная машина.
Всё, чем компьютеры оперировали — числа. Основным заказчиком и драйвером появления первых моделей были оборонные предприятия. На компьютерах проводили расчёты параметров полёта баллистических ракет, самолётов, спутников. В 1950-е годы вычислительные мощности компьютеров стали использовать для:
Компьютеры и числа
Цели, для которых разрабатывались компьютеры, привели к появлению архитектуры, предназначенной для работы с числами. Они хранятся в компьютере следующим образом:
В конце 1950-х годов происходит замена ламп накаливания на полупроводниковые элементы (транзисторы и диоды). Внедрение новой технологии позволило уменьшить размеры компьютеров, увеличить скорость работы и надёжность вычислений, а также повлияло на конечную стоимость. Если первые компьютеры были дорогостоящими штучными проектами, которые могли себе позволить только государства или крупные компании, то с применением полупроводников начали появляться серийные компьютеры, пусть даже и не персональные.
Компьютеры и символы
Постепенно компьютеры начинают применяться для решения не только вычислительных или математических задач. Возникает необходимость обработки текстовой информации, но с буквами и другими символами ситуация обстоит сложнее, чем с числами. Символы — это визуальный объект. Даже одна и та же буква «а» может быть представлена двумя различными символами «а» и «А» в зависимости от регистра.
Также число «один» можно представить в виде различных символов. Это может быть арабская цифра 1 или римская цифра I. Значение числа не меняется, но символы используются разные.
Компьютеры создавались для работы с числами, они не могут хранить символы. При вводе информации в компьютер символы преобразуются в числа и хранятся в памяти компьютера как обычные числа, а при выводе информации происходит обратное преобразование из чисел в символы.
Правила преобразования символов и чисел хранились в виде таблицы символов (англ. charset). В соответствии с такой таблицей для каждого компьютера конструировали и своё уникальное устройство ввода/вывода информации (например, клавиатура и принтер).
Распространение компьютеров
В начале 1960-х годов компьютеры были несовместимы друг с другом даже в рамках одной компании-производителя. Например, в компании IBM насчитывалось около 20 конструкторских бюро, и каждое разрабатывало свою собственную модель. Такие компьютеры не были универсальными, они создавались для решения конкретных задач. Для каждой решаемой задачи формировалась необходимая таблица символов, и проектировались устройства ввода/вывода информации.
В этот период начинают формироваться сети, соединяющие в себе несколько компьютеров. Так, в 1958 году создали систему SAGE (Semi-Automatic Ground Environment), объединившую радарные станций США и Канады в первую крупномасштабную компьютерную сеть. При этом, чтобы результаты вычислений одних компьютеров можно было использовать на других компьютерах сети, они должны были обладать одинаковыми таблицами символов.
В 1962 году компания IBM формирует два главных принципа для развития собственной линейки компьютеров:
Так в 1965 году появились компьютеры IBM System/360. Это была линейка из шести моделей, состоящих из совместимых модулей. Модели различались по производительности и стоимости, что позволило заказчикам гибко подходить к выбору компьютера. Модульность систем привела к появлению новой отрасли — производству совместимых с System/360 вычислительных модулей. У компаний не было необходимости производить компьютер целиком, они могли выходить на рынок с отдельными совместимыми модулями. Всё это привело к ещё большему распространению компьютеров.
ASCII как первый стандарт кодирования информации
Телетайп и терминал
Параллельно с этим развивались телетайпы. Телетайп — это система передачи текстовой информации на расстоянии. Два принтера и две клавиатуры (на самом деле электромеханические печатные машинки) попарно соединялись друг с другом проводами. Текст, набранный на клавиатуре у первого пользователя, печатается на принтере у второго пользователя и наоборот. Таким образом, например, была организована «горячая линия» между президентом США и руководством СССР вплоть до начала 1970-х годов.
Телетайпы также преобразуют текстовую информацию в некоторые сигналы, которые передаются по проводам. При этом не всегда используется бинарный код, например, в азбуке Морзе используются 3 символа — точка, тире и пауза. Для телетайпов необходимы таблицы символов, соответствие в которых строится между символами и сигналами в проводах. При этом для каждого телетайпа (пары, соединённых телетайпов) таблицы символов могли быть свои, исходя из задач, которые они решали. Отличаться, например, мог язык, а значит и сам набор символов, который отправлялся с помощью устройства. Для оптимизации работы телетайпа самые популярные (часто встречающиеся) символы кодировались наиболее коротким набором сигналов, а значит и в рамках одного языка, набор символов мог быть разным.
На основе телетайпов разработали терминалы доступа к компьютерам. Такой телетайп отправлял сообщения не второму пользователю, а информация вводилась на некоторый удалённый компьютер, который после обработки указанных команд, возвращал результат в виде ответного сообщения. Это нововведение позволило использовать тогда ещё очень дорогие вычислительные мощности компьютеров, не имея физического доступа к самому компьютеру. Например, компьютер мог размещаться в отдельном вычислительном центре корпорации или института, а сотрудники из других филиалов или городов получали доступ к вычислительным мощностями компьютера посредством установленных у них терминалов.
ASCII
Повсеместное распространение компьютеров и средств обмена текстовой информацией потребовало разработки единого стандарта кодирования для передачи и хранения информации. Такой стандарт разработали в США в 1963 году. Таблицу из 128 символов назвали ASCII — American standard code for information interchange (Американский стандарт кодов для обмена информацией).
Первые 32 символа в ASCII являются управляющими. Они использовались для того, чтобы, например, управлять печатающим устройством телетайпа и получать некоторые составные символы. Например:
Введение управляющих символов позволяло получать новые символы как комбинацию существующих, не вводя дополнительные таблицы символов.
Однако введение стандарта ASCII решило вопрос только в англоговорящих странах. В странах с другой письменностью, например, с кириллической в СССР, проблема оставалась.
Кодировки для других языков
В течение более чем 20 лет вопрос решали введением собственных локальных стандартов, например, в СССР на основе таблицы ASCII разработали собственные варианты кодировок КОИ 7 и КОИ 8, где 7 и 8 указывают на количество бит, необходимых для кодирования одного символа, а КОИ расшифровывается как Коды Обмена Информацией.
С дальнейшим развитием систем начали использовать восьмибитные кодировки. Это позволило использовать наборы, содержащие по 256 символов. Достаточно распространён был подход, при котором первые 128 символов брали из стандарта ASCII, а оставшиеся 128 дополнялись собственными символами. Такое решение, в частности, было использовано в кодировке KOI 8.
Однако единым стандартом указанные кодировки так и не стали. Например, в MS-DOS для русских локализаций использовалась кодировка cp866, а далее в среде MS Windows стали использоваться кодировки cp1251. Для греческого языка применялись кодировки cp851 и cp1253. В результате документы, подготовленные с использованием старой кодировки, становились нечитаемыми на новых.
Свои кодировки необходимы и для других стран с уникальным набором символов. Это приводило к путанице и сложностям в обмене информацией. Ниже приведён пример текста, который написали в кодировке KOI8-R, а читают в cp851.
Обе кодировки основаны на стандарте ASCII, поэтому знаки препинания и буквы английского алфавита в обеих кодировках выглядят одинаково. Кириллический текст при этом становится совершенно нечитаемым.
При этом компьютерная память была дорогой, а связь между компьютерами медленной. Поэтому выгоднее было использовать кодировки, в которых размер в битах каждого символа был небольшим. Таблица символов состоит из 256 символов. Это значит, что нам достаточно 8 бит для кодирования любого из них (2^8 = 256).
Переход к Unicode
Развитие интернета, увеличение количества компьютеров и удешевление памяти привели к тому, что проблемы, которые доставляла путаница в кодировках, стали перевешивать некоторую экономию памяти. Особенно ярко это проявлялось в интернете, когда текст написанный на одном компьютере должен был корректно отображаться на многих других устройствах. Это доставляло огромные проблемы как программистам, которые должны были решать какую кодировку использовать, так и конечным пользователям, которые не могли получить доступ к интересующим их текстам.
В результате в октябре 1991 года появилась первая версия одной общей таблицы символов, названной Unicode. Она включала в себя на тот момент 7161 различный символ из 24 письменностей мира.
В Unicode постепенно добавлялись новые языки и символы. Например, в версию 1.0.1 в середине 1992 года добавили более 20 000 идеограмм китайского, японского и корейского языков. В актуальной на текущий момент версии содержится уже более 143 000 символов.
Кодировки на основе Unicode
Unicode можно себе представить как огромную таблицу символов. В памяти компьютера записываются не сами символы, а номера из таблицы. Записывать их можно разными способами. Именно для этого на основе Unicode разработаны несколько кодировок, которые отличаются способом записи номера символа Unicode в виде набора байт. Они называются UTF — Unicode Transformation Format. Есть кодировки постоянной длины, например, UTF-32, в которой номер любого символа из таблицы Unicode занимает ровно 4 байта. Однако наибольшую популярность получила UTF-8 — кодировка с переменным числом байт. Она позволяет кодировать символы так, что наиболее распространённые символы занимают 1-2 байта, и только редко встречающиеся символы могут использовать по 4 байта. Например, все символы таблицы ASCII занимают ровно по одному байту, поэтому текст, написанный на английском языке с использованием кодировки UTF-8, будет занимать столько же места, как и текст, написанный с использованием таблицы символов ASCII.
На сегодняшний день Unicode является основной кодировкой, которую используют в работе все, кто связан с компьютерами и текстами. Unicode позволяет использовать сотни тысяч различных символов и отображать их одинаково на всех устройствах от мобильных телефонов до компьютеров на космических станциях.
Unicode: визуализация занятого пространства и объяснение тех аспектов, которые должен знать каждый программист
Авторизуйтесь
Unicode: визуализация занятого пространства и объяснение тех аспектов, которые должен знать каждый программист
Unicode — это слово вызывает страх и трепет в сердцах миллионов программистов по всему миру. Несмотря на то, что все мы пытаемся «поддерживать Unicode» в нашем софте, Unicode — это не просто использование wchar_t для строк, это стандарт из тысячи страниц и десятки дополнений к нему. Поэтому спустя 30 лет после появления Unicode многие программисты всё ещё понятия не имеют, что же это на самом деле такое.
Разнообразие и сложность
Как только вы начинаете изучать Unicode, сразу же становится понятно, что это «явление» намного сложнее, чем та же таблица ASCII, с которой вы уже можете быть знакомы. Дело не только в том, что Unicode содержит намного больше символов. Unicode имеет сложную внутреннюю структуру, фичи и набор разноцветных костылей, и это явно не те вещи, которые вы ожидаете от простой таблицы символов.
Но во многом именно благодаря этому Unicode поддерживает все или почти все системы письменности, которые существуют в мире: на сегодня этот стандарт поддерживает более чем 1100 языков. Но его задача не только в том, чтобы вместить все возможные языки, но и в том, чтобы позволить им сосуществовать в одном тексте — это делает задачу ещё сложнее.
Тем не менее, разбираться в особенностях Unicode всё-таки следует любому программисту: подумайте о миллионах людей, которые смогут использовать ваше ПО на своем родном языке.
Кодовое пространство
Начнем с основ. Базовые элементы — это символы, хотя правильнее будет всё же использовать термин «кодовые точки». Кодовые точки определяются по шестнадцатеричному номеру и префиксу «U+». Например, U+0041 это латинская буква «A», а U+03B8 — греческая «θ». Каждая кодовая точка также имеет собственное название и ещё несколько характеристик, указанных в базе данных символов Unicode.
Множество всех возможных кодовых точек называется кодовым пространством. Кодовое пространство Unicode состоит из 1 114 112 кодовых точек. Но лишь 128 237 (12%) из них на самом деле являются занятыми: более чем достаточно места для роста. Юникод также резервирует 138 468 кодовых точек для «приватного использования», то есть для внутренних нужд различных приложений.
Распределение кодового пространства
Лучший способ что-то понять — использовать визуализацию. (Кстати, если вы хотите понять суть каких-нибудь алгоритмов, у нас есть для вас подборка сервисов с визуализацией алгоритмов.) Ниже представлена карта всего кодового пространства, каждый пиксель соответствует одной кодовой точке. Для удобства карта поделена на поля (маленькие квадраты) размером 16×16 = 256 кодовых точек. Каждое большое поле содержит 65 536 кодовых точек. Всего существует 17 больших полей.
Белым цветом помечено незанятое пространство, синим — уже определенные символы, а зеленым – приватные кодовые точки. Красным цветом обозначены суррогатные точки, которые являются результатом особенностей кодирования в UTF-16, о них мы поговорим позже.
Первое большое поле называется «Базовое мультиязычное поле». Оно содержит почти все символы, которые используются в современных текстах, включая латинские буквы, кириллицу, греческий, китайский, японский, корейский и так далее. В своей первой версии Unicode состоял только из этого поля и был расширен лишь в 1996 году.
Второе поле содержит исторические и специальные символы, например, сумерийскую клинопись, египетские иероглифы и эмодзи. Третье поле содержит небольшое количество менее известных китайских символов. Остальные поля остаются пустыми, не считая небольшого количества редко используемых символов форматирования в 15 поле. Поля 16-17 целиком в приватном использовании.
Языки, поддерживаемые Unicode
Давайте сосредоточимся на первых трех полях, именно там происходит всё самое интересное:
Эта цветная карта обозначает 135 различных языков юникода. Китайский (бирюзовый) и корейский (коричневый) занимают основную часть базового поля (левый большой квадрат). Для сравнения, все европейские, средневосточные и южноазиатские языки вместились в первую строку базового поля.
По частоте использования в реальном мире лидирует первое поле, исключением являются эмодзи — они завоевали наши сердца, находясь во втором поле.
Кодировки
Как вы узнали раньше, кодовые точки задаются номерами с U+0000 по U+10FFFF. Но как эти номера хранятся в реальной памяти компьютера? Использование первого, что приходит в голову – обычного 32-битного целочисленного типа – было бы очень ресурсоемким и не оправданным. Нам понадобилось бы по 4 байта на каждую кодовую точку. Поэтому тут на помощь нам приходят стандарты кодирования UTF — Unicode Transformation Format.
Некоторые программисты считают, что Unicode и UTF — это разные вещи, но на самом деле UTF-8, UTF-16 и UTF-32 являются лишь стандартами преобразования UTF, которые позволяют значительно сэкономить память и повысить скорость обработки.
Например, в UTF-8 символы с кодами меньше 128 представляются всего одним байтом, а так как в Юникоде они повторяют ASCII, то текст, написанный только этими символами, будет являться текстом в ASCII — это позволяет избежать лишних конвертаций. Символы же с кодами от 128 до 65536 кодируются 2-мя байтами, аналогично существуют 3-байтные и 4-байтные коды.
Смысл UTF-16 и UTF-32 в том, чтобы представить ещё большую часть Unicode как обычную таблицу, подобную ASCII. Например, UTF-32 — это и есть большая таблица ASCII для всего юникода, но в 99% случаев хватает и UTF-8.
Комбинации знаков
До этого мы обсуждали только кодовые точки, но в юникоде символ может быть больше, чем одной кодовой точкой. Комбинации созданы для экономии памяти: именно с их помощью ставятся ударения и другие крючочки под и над буквами.
Например, букву под ударением (Á) можно описать таким образом: U+0041 (A) + U+0301 (`).
Видели в интернете м̵͉̪̫̳̖͌͋͗͌̑̎а̬̜ͣͤг̘͎̹̜͕̤͊̊̽и͕̽͌ͮͬ͡ю͉͑̏ ̛̹̬̜̪̳̹̙̿̄͋̏т̹̫͚̱̩ͅи̼̬̤̓͒ͨ̅́́̚̚п̗̔̒ͧ̇ͩ̐̔а̺̄͆ͭ ̢̜͉̮̭͚ͬ͒͐̈̚т̛̦̖͎̪̭͇̓а̛͙̳̼̺̲̜̂ͮͦ̈́̃̈́ͣк̳̘̝̔́о͉̜̆̈́й͉͍̜͛͆́̀? Она создается именно с помощью комбинации знаков.
И это только начало
Эта статья содержит более 5 000 символов, но на самом деле является лишь верхушкой айсберга. Юникод полон других сложных вещей: чего стоят одни только применения (mapping), сопоставления (collation) и двунаправленный текст. Но и это далеко не всё.
Юникод — очень сложная система. И хотя для работы программистом вам не обязательно понимать её полностью, некоторые знаний всё-таки станут полезными на практике.
Если хотите узнать больше, то можете прочитать следующие материалы:
Но что вы точно обязаны сделать, так это поблагодарить юникод за то, что мы больше никогда не вернемся в старые времена несовместимых кодировок.