Спецсеминар "Разработка свободного ПО": http://uucode.com/oss2004/. 12-я лекция, 27 ноября 2004.
Unicode -- это не кодировка, это "реестр" символов. Иногда слоэно различить "одинаковые" и "разные" буквы. Буквам сопоставлены "магические числа".
Например, "ё" (русская йо):
Поиск символов, преобразование различных представлений: http://www.zvon.org/other/charSearch/PHP/search.php
По-быстрому получить "магический" код символа:
$ echo -n 'ё' | iconv -f koi8-r -t ucs2 | od -t x2 0000000 0451
Важно: unicode -- это не кодировка. Это абстрактное описание. International standard ISO/IEC 10646.
Яva: U+042f U+0076 U+0061
А теперь про кодировки.
"Яva": 04 2f 00 76 00 61 "Яva": 2f 04 76 00 61 00
Делают и так, и так. "FE FF" -- BOM -- Unicode Byte Order Mark. UCS-2/UTF-16, два варианта из-за BOM
Unicode не всем понравился: слишком большой расход памяти. Особенно в UCS-4.
September 2, 1992, Pike и Thompson придумали за обедом utf8, а затем реализовали её, и система plan9 стала всюду использовать utf8.
UTF-8 (8-bit Unicode Transformation Format). RFC 3629.
Таблица перевода:
000000-00007F: 0xxxxxxx 000080-0007FF: 110xxxxx 10xxxxxx 000800-00FFFF: 1110xxxx 10xxxxxx 10xxxxxx 010000-10FFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Пример:
Я: 0x042f: 10000101111 -> 10000.101111 -> 11010000 10101111 -> D0 AF va: 76 61 Яva: D0 AF 76 61
А ещё бывают UTF-16 и UTF-7. А ещё у Явы (и, наверное, не только) своё представление об UTF-8.
Очевидные свойства:
Плюсы:
Минусы:
Зачёт: продемонстрировать на примере "Яva" как буква "Я" кодируется разными последовательностями.
Важно. Не бывает такого понятия как "просто текст"! Строка без знания кодировки бессмысленна.
Способы задания кодировки:
В некоторых случаях кодировку не указать: zip-архивы, mp3 tags. И тогда всё плохо.
Транспортная кодировка:
C/C++:
Java/C#/Python/etc -- внутри utf8. Но не без проблем.
Когда "тест"!="тест" (первое введено пользователем в web-формочку, второе -- в исходный код программы). Указание кодировки при компиляции программы или использование unicode-escapes. Второе лучше и надёжнее.
Кодировка -- это хорошо, но правильные программы должны учитывать "культуру". Пример локали:
ru_RU.koi8-r
Обычно задаётся переменной окружения "LC_ALL". Есть и другие переменные для тонкой настройки, их список -- в любой книжке про unix. По умолчанию "C" или "POSIX".
Добавить пояснение, почему регэкспы и токеназеры не работают. Либо код криво написан, либо не выставлена локаль.
LC_NUMERIC стоит всегда держать в "C" или "POSIX". О проблемах говорили в прошлый раз.
Про LC_COLLATE. Почему нельзя использовать "наивные" сортировки.
В некоторых ОС локаль не меняется.
Проблема DOS'овского чёрного окна. А нём используется oem-кодировка (например, cp866). Поэтому "type file.txt" выводит нечитаемый текст. В принципе, кодировку можно поменять, но тогда "призовая игра":
"cmd.com ..." vs "cmd.com ... | more.
От этого пока никуда не деться.
Проблема: делаем "print(str)", "str" содержит "u:", а выходная кодировка "koi8-r". Что случится?
Это не лечится. Надо внимательно работать с кодировками reader'ов, writer'ов и stream'ов, и знать что в какой кодировке находится. Проще всего входящие данные сразу преобразовывать в unicode.
Важно: При отладке unicode-действий нельзя использовать для отладки просто print. Ведь при этом происходит преобразование, и на выходе получается неправда. Правильный способ -- написать и использовать функцию "asciify", которая символы [^A-Za-z0-9] преобразует в коды типа "У".
Про него уже говорили. Код пишется примерно так:
print(_("Hello, World!"))
Специальная программа вытаскивает строки, тексты переводятся на другие языки (po-файлы), результаты компилируются (mo-файлы). Есть GUI.
gettext есть для почти всех языков программирования, в том числе и для php.
Можно использовать не только для текста, но и для других данных.
В .NET есть что-то подобное.
В названии unicode-шрифтов обычно присутствует "iso-10446-1".
Если вывести мусор на терминал, то иногда можно что-нибудь исполнить.
В MSDN есть хорошая книжка про l10n и i18n. Рекомендую.
Флаги на сайтах надо использовать аккуратно (например, что использовать для английского языка?). Более тяжёлый случай: http://www.linux.org.ru/view-message.jsp?msgid=665958&page=0 "Флажки запрещены по соображениям политкорректности".