1 О кодировках символов в компьютере 1. Кодовая таблица - таблица соответствий символов и их компьютерных кодов. В РФ распространены следующие кодировки: WIN1251 (Windows), KOI-8 (Unix), СP866 (DOS), Macintosh, ISO-8859-5 (Unix). 2. http://online.multilex.ru/default.asp?artsub=1&article=1470303510&art=1&lang=4.0er&dictionary=E NRUcomp Компьютер (EN-RU) Unicode кодовая таблица Unicode # стандарт кодирования (представления) символов всех национальных алфавитов. В этом коде для представления каждого символа используется уникальная 16-битовая комбинация (см. также DBCS, www.unicode.org). 3. http://www.sensi.org/~alec/unicode/index.html#what Что такое UNICODE? [ISO10646] ISO/IEC 10646-1:1993 International Organization for Standardization. "Information Technology -- Universal Multiple-Octet Coded Character Set (UCS) -- Part 1: Architecture and Basic Multilingual Plane", Geneva, 1993. [UNICODE] The Unicode Standard, Version 2.0, The Unicode Consortium, Addison-Wesley, July 1996. UNICODE - частичная реализация стандарта ISO 10646, совместим снизу вверх, т.е. первые 256 символов UNICODE = Latin-1 (ISO 8859-1). FYI: В настоящее время распределено около 29.000 позиций из 65.535 возможных. 681454073 2 4. http://www.suncloud.ru/workshop/wdhplus/encoding/encoding2.htm О кодировках символов Национальные кодировки Определения Кодировки латиницы Кодировки кириллицы Двухбайтовые кодировки Недостатки национальных кодировок Стандарт Unicode История стандарта Общее описание Трансформационные форматы Проблемы реализации Аннотация. В «Справочнике Веб-разработчика» (http://wdh.suncloud.ru/) кодировкам символов уделено достаточно большое внимание. Однако, вопросы читателей показывают, что необходимы дополнительные пояснения, и я счел полезным собрать основные сведения о кодировках в одном месте. Для удобства чтения эта статья разбита на две страницы. Национальные кодировки Определения Начнем с определения понятий. Современные компьютеры хранят всю информацию в виде двоичных байтов, т. е. 8-битовых единиц, способных принимать значение от 0 до 255. Для того, чтобы сохранить в памяти компьютера не числовую, а текстовую информацию, мы должны определить, каким байтом или байтами будет кодироваться каждый символ, который может встретиться в нашем тексте. Такое соответствие между символами и кодирующими их байтами и называется кодировкой символов (character set). Нетрудно понять, во-первых, что каждая кодировка разрабатывается для конкретного человеческого языка (точнее, для конкретной письменности), и, во-вторых, что для любого языка таких кодировок можно придумать сколько угодно. Зная человеческую натуру, нетрудно догадаться и о том, что придумают их гораздо больше, чем нужно. Естественно, так и случилось: наиболее развитая на сегодня библиотека функций перекодировки ICU (International Components for Unicode) корпорации IBM поддерживает более 170 различных кодировок. Кодировки латиницы Рассмотрим подробнее кодировки тех письменностей, с которыми чаще всего сталкивается российский разработчик, т. е. латиницы и кириллицы. Для латиницы на сегодня используются две основные кодировки: ASCII и EBCDIC. ASCII (American Standard Code for Information Interchange) — это семибитная кодовая таблица (коды символов 00 - 7F или 0 - 127 десятичные), ставшая стандартом для малых и средних компьютеров, а потому и стандартом для Веба. В ней байты с шестнадцатеричными кодами 00 — 1F и 7F используются для кодирования управляющих (неотображаемых) символов, а остальные кодируют следующие символы: 681454073 3 Кодировка EBCDIC (Extended Binary-Coded Decimal Interchange Code) — это восьмибитная кодировка (коды символов 00 - FF или 0 - 255 десятичные), принятая на всех компьютерах IBM, кроме PC. Можно было бы ее не упоминать, но по мере развития XML как основного формата транспорта данных в Сети мы все чаще будем сталкиваться с XML-файлами, сгенерированными на больших машинах. Здесь байты с кодами 00 — 3F кодируют управляющие символы, а остальные используются так: Кодировки кириллицы Кодировки «нелатинских» алфавитных письменностей устроены следующим образом. Они кодируются восьмибитовой таблицей (1 байт = 1 символ), т. е. числами 00 - FF (0 - 255 десятичные) так, что младшая половина кодовой таблицы (коды 00 - 7F или 0 - 127 десятичные) совпадает с ASCII, а старшая половина (коды 80 - FF или 128 - 255 десятичные) содержит национальную кодировку, т. е. русские буквы в русских кодовых таблицах, турецкие в турецких и т. д. Такая организация национальных кодовых таблиц позволяет правильно отображать и обрабатывать латинские буквы, цифры и знаки препинания на любом компьютере, независимо от его системных настроек. Именно так, в частности, устроены и русские кодовые таблицы, так что мы можем в дальнейшем рассматривать только старшую их половину. История русских кодировок — это пример неразберихи, редкостной даже для нашей компьютерной действительности. Советские стандартизирующие организации принимали ГОСТы, производители компьютеров (Apple) и операционных систем (Microsoft) их дружно игнорировали и вводили собственные кодировки. В результате мы получили наследство из четырех разных ГОСТов, две кодировки от Microsoft (для DOS и для Windows) и кодировку от Apple для Mac'ов (все, естественно, несовместимые между собой). Интересующиеся подробностями могут обратиться к странице The Cyrillic Charset Soup. К счастью, сегодня нет нужды подробно описывать все эти кодировки, поскольку в Рунете выжили только две из них. Первая — это КОИ8-Р (КОИ означает Код для Обмена и обработки Информации, Р отличает русскую кодовую таблицу от украинской, КОИ8-У). КОИ8Р была зарегистрирована Андреем Черновым из Релкома в качестве RFC 1489 и имеет вид: 681454073 4 КОИ8-Р является стандартом de facto для всех служб Интернета, кроме WWW. В частности, все службы электронной почты и новостей Рунета работают в этой кодировке. Что касается Веба, то здесь ситуация сложнее. Дело в том, что более 90% клиентских компьютеров Сети работает под управлением Windows разных версий. Windows использует собственную кодировку русских букв, которую принято назвать по номеру кодовой страницы Windows-1251 или CP1251: Поскольку текстовые редакторы и средства разработки HTML-страниц в Windows работают в этой кодировке, абсолютное большинство Веб-документов Рунета хранится в кодировке Windows-1251. Двухбайтовые кодировки Не следует думать, что все национальные кодировки являются байтовыми, т. е. следуют правилу: 1 символ = 1 байт. На самом деле, это справедливо только для алфавитных (буквеннозвуковых) систем письменности. С другой стороны, существуют силлабические системы письма, в которых каждый символ представляет не звук, а слог, например, индийские и дальневосточные слоговые азбуки. Поскольку слогов в языке намного больше, чем отдельных звуков, старших 128 байтов кодовой таблицы просто недостаточно для их представления. Это приводит к тому, что такие письменности используют двухбайтовые кодировки (DBCS, Double Byte Character Sets). Типичным примером такой кодировки является японская кодировка JIS, существующая в нескольких вариантах. Она охватывает латинские буквы и цифры, обе японские слоговые азбуки (катакану и хирагану) и важнейшие из китайских иероглифов. Но полноценное представление иероглифической письменности Китая, Японии и Кореи, насчитывающей несколько тысяч иероглифов, в рамках национальных кодировок остается невозможным. Недостатки национальных кодировок Несомненным достоинством традиционных кодовых таблиц является предельная краткость представления текстовой информации. Однако, эта краткость влечет за собой и несколько недостатков, органически с ней связанных: Поскольку символы разных языков представляются одними и теми же значениями от 0 до 255, то для правильной их визуализации исполняющая система должна знать не только код символа, но и название кодовой таблицы. При этом, несмотря на все усилия стандартизаторов, разнобой в названии кодировок полный (например, ASCII может называться 681454073 5 ANSI_X3.4-1968, ANSI_X3.4-1986, cp367, csASCII, IBM367, iso-ir-6, ISO646-US, ISO_646.irv:1991, ascii, us, us-ascii, us-ascii-1968, x-ansi; синонимы для других кодировок см. в WDH: Стандартные кодировки символов). По этой же причине оказывается практически невозможным сочетание нескольких кодовых таблиц в одном документе. Это ведет к «типографской бедности» текстовых документов, поскольку громадное число полезных символов, не входящих в данную национальную кодировку, выбрасывается за борт. Кодовые таблицы, ориентированные на алфавитные системы письма, не смогли решить проблему кодирования дальневосточных иероглифов и индийских слоговых азбук. Между прочим, это означает, что почти половина населения Земли лишена возможности работать с компьютером на родном языке. По мере того, как компьютеры становились мощнее, Интернет — разветвленнее, а операционные системы — дружелюбнее к пользователю, перечисленные недостатки оказывались все более серьезным препятствием на пути к созданию естественных интерфейсов «человек-компьютер» и «компьютер-Сеть». Выход из ситуации был достигнут созданием стандарта Unicode, о котором пойдет речь на следующей странице. Юрий Лукач © 2002 Suncloud.Ru Стандарт Unicode История стандарта Стандарт Unicode или ISO/IEC 10646 явился результатом сотрудничества Международной организации по стандартизации (ISO) с ведущими производителями компьютеров и программного обеспечения. Причины, изложенные на предыдущей странице, привели их к принципиально новой постановке вопроса: зачем тратить усилия на развитие отдельных кодовых таблиц, если можно создать единую таблицу для всех национальных языков? Такая задача кажется излишне амбициозной, но только на первый взгляд. Дело в том, что из 6700 живых языков официальными языками государств являются около полусотни, причем пользуются они примерно 25 различными письменностями: числа для нашего компьютерного века вполне обозримые. Предварительная прикидка показала, что для кодирования всех этих письменностей достаточно 16-битового диапазона, т. е. диапазона от 0000 до FFFF. Каждой письменности был выделен свой блок в этом диапазоне, который постепенно заполнялся кодами символов этой письменности. На сегодня кодирование всех живых официальных письменностей можно считать завершенным. Отработанная методика анализа и описания систем письма позволила консорциуму Unicode перейти в последнее время к кодированию остальных письменностей Земли, которые представляют какой-либо интерес: это письменности мертвых языков, выпавшие из современного обихода китайские иероглифы, искусственно созданные алфавиты и т. п. Для представления всего этого богатства 16-битового кодирования уже недостаточно, и сегодня Unicode использует 21-битовое пространство кодов (000000 - 10FFFF), которое разбито на 16 зон, названных плоскостями. Пока что в планах Unicode предусмотрено использование следующих плоскостей: Плоскость 0 (коды 000000 - 00FFFF) — БМП, базовая многоязыковая плоскость (BMP, Basic Multilingual Plane), соответствует исходному диапазону Unicode. Плоскость 1 (коды 010000 - 01FFFF) — ДМП, дополнительная многоязыковая плоскость (SMP, Supplementary Multilingual Plane), предназначена для мертвых письменностей. Плоскость 2 (коды 020000 - 02FFFF) — ДИП, дополнительная иероглифическая плоскость (SIP, Supplementary Ideographic Plane), предназначена для иероглифов, не попавших в БМП. Плоскость 14 (коды 0E0000 - 0EFFFF) — ДСП, дополнительная специальная плоскость (SSP, Supplementary Special-purpose Plane), предназначена для символов специального назначения. 681454073 6 Плоскость 15 (коды 0F0000 - 0FFFFF) — плоскость частного пользования (PrivateUse Plane), предназначена для символов искусственных письменностей. Плоскость 16 (коды 100000 - 10FFFF) — плоскость частного пользования (PrivateUse Plane), предназначена для символов искусственных письменностей. Разбивка БМП на блоки приведена в WDH: Стандарт Unicode. Здесь отметим только, что первые 128 кодов (00000 - 0007F) соответствуют кодам ASCII и кодируют блок базовой латиницы. Подробно раскладка письменностей по диапазону Unicode будет описана в моей статье «Unicode и письменности мира». Поскольку нас в дальнейшем будут интересовать только символы БМП, я использую их 16-битовые коды вида XXXX (старшие биты равны нулю и не указываются). Действующей версией стандарта является Unicode 3.1, принятый в мае 2001 г. Все подробности можно найти на официальном сайте www.unicode.org. Общее описание В основе Unicode лежит понятие символа (character). Символ — это абстрактное понятие, которое существует в конкретной письменности и реализуется через свои изображения (графемы). Это означает, что каждый символ задается уникальным кодом и принадлежит к конкретному блоку Unicode. Например, графема А есть и в английском, и в русском, и в греческом алфавитах. Однако, в Unicode ей соответствуют три разных символа «латинская прописная буква А» (код 0041), «кириллическая прописная буква А» (код 0410) и «греческая прописная буква АЛЬФА» (код 0391). Если мы теперь применим к этим символам преобразование в строчную букву, то соответственно получим «латинскую строчную букву А» (код 0061, графема a), «кириллическую строчную букву А» (код 0430, графема а) и «греческую строчную букву АЛЬФА» (код 03B1, графема α), т. е. разные графемы. Может возникнуть вопрос: что такое преобразование в строчную букву? Здесь мы подходим к самому интересному и важному моменту в стандарте. Дело в том, что Unicode — это не просто кодовая таблица. Концепция абстрактного символа позволила создателям Unicode построить базу данных символов, в которой каждый символ описывается своим уникальным кодом (ключом базы данных), полным названием и набором свойств. Например, символ с кодом 0410 описан в этой базе так: 0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430; Расшифруем эту запись. Она означает, что код 0410 присвоен «кириллической прописной букве А» (полное название символа), которая имеет следующие свойства: строчная буква (Lu = Letter, uppercase) Общая категория Класс сочетаний 0 Направление вывода слева направо (L) Декомпозиция символа нет Десятичная цифра нет Цифра нет Числовое значение нет Зеркальный символ отсутствует (N) Полное Unicode 1.0 название в Комментарий Отображение 681454073 то же нет в нет 7 прописную букву Отображение в строчную букву Отображение титульную букву в 0430 нет Перечисленные свойства определены для каждого символа Unicode. Это позволило его разработчикам создать стандартные алгоритмы, которые определяют на основе свойств символов правила их визуализации, сортировки и преобразования в прописные/строчные буквы. В итоге можно сказать, что стандарт Unicode состоит из трех взаимосвязанных частей: базы данных символов; базы графем (glyphs), определяющих визуальное представление этих символов; набора алгоритмов, определяющих правила работы с символами. В заключение этого раздела приведем графемы блока кириллицы (коды 0400 - 04FF). Обратите внимание, что он включает в себя не только буквы современных кириллических алфавитов (русского, украинского, белорусского, болгарского, сербского, македонского и пр.), но и все буквы первоначальной кириллицы, использовавшиеся в церковнославянской письменности. 681454073 8 Трансформационные форматы Как мы видели, каждый символ Unicode имеет уникальный 21-битовый код (code point). Однако, для практической реализации такая кодировка символов неудобна. Дело в том, что операционные системы и сетевые протоколы традиционно работают с данными как с потоками байтов. Это приводит, как минимум, к двум проблемам: Порядок байтов в слове у разных процессоров различен. Процессоры Intel, DEC и др. хранят в первом байте машинного слова его старший байт, а процессоры Motorola, Sparc и др. — младший байт. Их соответственно называют little-endian и big-endian (эти термины происходят от «остроконечников» и «тупоконечников» у Свифта, споривших о том, с какого конца нужно разбивать яйца). Многие байт-ориентированные системы и протоколы допускают использование в качестве данных только байтов из определенного диапазона. Остальные байты рассматриваются как служебные; в частности, нулевой байт принято использовать как символ конца строки. Поскольку Unicode кодирует символы подряд, прямая передача его кодов как цепочки байтов может войти в противоречие с правилами протокола передачи данных. Для преодоления этих проблем стандарт включает в себя три трансформационных формата UTF-8, UTF-16 и UTF-32, которые определяют соответственно правила кодирования символов Unicode цепочками байтов, парами 16-битовых слов и 32-битовыми словами. Выбор используемого формата зависит от архитектуры вычислительной системы и стандартов хранения и передачи данных. Краткое описание трансформационных форматов можно найти в WDH: Стандарт Unicode. Проблемы реализации Думаю, что даже из приведенного выше краткого описания стандарта Unicode ясно, что его полная поддержка основными операционными системами будет означать революцию в области обработки текстов. Пользователь, сидящий за любым терминалом Сети, сможет выбрать любую раскладку клавиатуры, набрать текст на любом языке и передать его на любой компьютер, который правильно этот текст отобразит. Базы данных смогут хранить, правильно сортировать и выводить в отчеты текстовую информацию опять-таки на любом языке. Для того, чтобы этот рай наступил, необходимы пять вещей: 1. Операционные системы должны поддерживать трансформационные форматы Unicode на уровне ввода, хранения и отображения текстовых строк. 2. Необходимы «умные» драйверы клавиатур, позволяющие нам вводить символы любого блока Unicode и передающие их коды операционной системе. 3. Текстовые редакторы должны поддерживать отображение всех символов Unicode и выполнять над ними общепринятый набор символьных операций. 4. То же самое должно правильно выполняться СУБД в отношении текстовых и memo-полей. 5. Поскольку национальные кодировки еще долгое время будут сосуществовать с Unicode, необходима поддержка преобразований текста между ними. С сожалением приходится признать, что за десять лет (Unicode 1.0 появился в 1991 г.) в этом направлении сделано гораздо меньше, чем хотелось бы. Даже Windows, содержащая на системном уровне наиболее последовательную поддержку Unicode, полна абсолютно иррациональных ограничений, объясняемых только ее историческим развитием. В Unix ситуация еще хуже, поскольку здесь поддержка Unicode перенесена из ядра на конкретные приложения. Можно утверждать, что на сегодня наиболее серьезно Unicode поддерживается в двух средах: веб-браузерах и виртуальных Java-машинах. Это не удивительно, поскольку обе среды изначально создавались как системно-независимые. Следует отметить и объективные трудности поддержки Unicode. Для примера остановимся только на отображении графем, для которого нужно установить в системе соответствующие шрифты. Проблема в том, что шрифт, содержащий все графемы Unicode будет иметь совершенно несуразный размер. Например, TrueType-шрифт Arial Unicode MS, содержащий большую порцию символов Unicode, «весит» 24Мб. По мере наполнения Unicode новыми блоками размер таких шрифтов приблизится к 100Мб. Выходом из положения может 681454073 9 послужить предложенная Microsoft загрузка символов по требованию, принятая в их браузере Internet Explorer. Однако, пока стандарты о правилах формирования Unicode-шрифтов молчат. Способы работы с символами Unicode и национальных кодировок в важнейших средах и системах программирования будут рассмотрены в следующих статьях. Юрий Лукач © 2002 Suncloud.Ru 681454073