Разное

Unicode и ascii сравнение: Почему Python печатает символы юникода, когда кодировка по умолчанию-ASCII?

Содержание

Почему Python печатает символы юникода, когда кодировка по умолчанию-ASCII?

благодаря кусочкам из разных ответов, я думаю, мы можем сшить объяснение.

пытаясь напечатать строку unicode, u ‘\xe9’, Python неявно пытается кодировать эту строку, используя схему кодирования, хранящуюся в sys.стандартный вывод.кодирование. Python фактически берет эту настройку из среды, из которой она была инициирована. Если он не может найти правильную кодировку из среды, только тогда он возвращается к своему по умолчанию, ФОРМАТ ASCII.

например, я использую оболочку bash, кодировка которой по умолчанию равна UTF-8. Если я запускаю Python из него, он берет и использует эту настройку:

$ python

>>> import sys
>>> print sys.stdout.encoding
UTF-8

давайте на мгновение выйдем из оболочки Python и установим среду bash с некоторой фиктивной кодировкой:

$ export LC_CTYPE=klingon
# we should get some error message here, just ignore it. 

затем снова запустите оболочку python и убедитесь, что она действительно возвращается к кодировке ascii по умолчанию.

$ python

>>> import sys
>>> print sys.stdout.encoding
ANSI_X3.4-1968

Бинго!

если вы теперь попытаетесь вывести некоторые символ Юникода вне ascii вы должны получить хорошее сообщение об ошибке

>>> print u'\xe9'
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' 
in position 0: ordinal not in range(128)

позволяет выйти из Python и отбросить оболочку bash.

теперь мы рассмотрим, что происходит после вывода строк Python. Для этого мы сначала запустим оболочку bash в графическом терминале (я использую терминал Gnome), и мы установим терминал для декодирования вывода с помощью ISO-8859-1 aka latin-1 (графические терминалы обычно имеют опцию Установить Кодировку Символов в одном из своих выпадающее меню.) Обратите внимание, что это не изменяет фактическое оболочка окружающей среды кодировка, она только изменяет способ терминал сам будет декодировать вывод, который он дал, немного как веб-браузер. Поэтому вы можете изменить кодировку терминала независимо от среды оболочки. Затем давайте запустим Python из оболочки и проверим, что sys.стандартный вывод.кодировка установлена в кодировку среды оболочки (UTF-8 для меня):

$ python

>>> import sys

>>> print sys.stdout.encoding
UTF-8

>>> print '\xe9' # (1)
é
>>> print u'\xe9' # (2)
é
>>> print u'\xe9'.encode('latin-1') # (3)
é
>>>

(1) python выводит двоичную строку как есть, терминал получает ее и пытается сопоставить ее значение с картой символов latin-1. На латыни-1, 0xe9 или 233 дает символ «é», и это то, что отображает терминал.

(2) python пытается имплицитно кодируйте строку Unicode с любой схемой, установленной в настоящее время в sys.стандартный вывод.кодировка, в данном случае это «UTF-8». После кодирования UTF-8 результирующая двоичная строка является «\xc3\xa9 » (см. более позднее объяснение). Терминал получает stream как таковой и пытается декодировать 0xc3a9 с помощью latin-1, но latin-1 идет от 0 до 255 и поэтому декодирует только потоки по 1 байту за раз. 0xc3a9 имеет длину 2 байта, поэтому декодер latin-1 интерпретирует его как 0xc3 (195) и 0xa9 (169), что дает 2 символа: Ã и ©.

(3) python кодирует кодовую точку Юникода u’\xe9′ (233) по схеме latin-1. Оказывается, диапазон кодовых точек latin-1 равен 0-255 и указывает на тот же символ, что и Unicode в этом диапазоне. Таким Образом, В Кодировке Unicode кодовые точки в этом диапазоне будут давать одно и то же значение при кодировании на латинице-1. Таким образом, u’\xe9′ (233), закодированный на латыни-1, также даст двоичную строку ‘\xe9’. Терминал получает это значение и пытается сопоставить его на карте символов latin-1. Как и в случае (1), он дает «é», и это то, что отображается.

давайте теперь изменим настройки кодирования терминала на UTF-8 из выпадающего меню (например, вы измените настройки кодирования вашего веб-браузера). Нет необходимости останавливать Python или перезапускать оболочка. Кодировка терминала теперь соответствует кодировке Python. Попробуем напечатать еще раз:

>>> print '\xe9' # (4)

>>> print u'\xe9' # (5)
é
>>> print u'\xe9'. encode('latin-1') # (6)

>>>

(4) python выводит бинарные строку как есть. Терминал пытается декодировать этот поток с помощью UTF-8. Но UTF-8 не понимает значение 0xe9 (см. более позднее объяснение) и поэтому не может преобразовать его в кодовую точку unicode. Кодовая точка не найдена, символ не напечатан.

(5) python пытается имплицитно кодировать строку в Юникоде с тем, что в sys.стандартный вывод.кодирование. Еще «UTF-8». Результирующая двоичная строка — ‘\xc3\xa9’. Терминал получает поток и пытается декодировать 0xc3a9 также с помощью UTF-8. Он возвращает значение кода 0xe9 (233), которое на карте символов Юникода указывает на символ «é». Терминал отображает «é».

(6) python кодирует строку unicode с латиницей-1, она дает двоичную строку с тем же значением ‘\xe9’. Опять же, для терминала это почти то же самое, что и case (4).

выводы:
— Python выводит строки, отличные от unicode, в качестве исходных данных, без учета кодировки по умолчанию. Терминал просто отображает их, если его текущая кодировка соответствует данным.
— Python выводит строки Unicode после их кодирования по схеме, указанной в sys.стандартный вывод.кодирование.
— Python получает эту настройку из среды оболочки.
— терминал отображает вывод в соответствии с собственными настройками кодирования.
— кодировка терминала не зависит от Шелла.


более подробная информация о unicode, UTF-8 и latin-1:

Unicode-это в основном таблица символов, в которой некоторые ключи (кодовые точки) обычно назначаются для указания на некоторые символы. например, по соглашению было решено, что ключ 0xe9 (233) является значением, указывающим на символ «é». ASCII и Unicode используют те же кодовые точки от 0 до 127, что и latin-1 и Unicode от 0 до 255. То есть 0x41 указывает на » A » в ASCII, latin-1 и Юникод, 0xc8 указывает на ‘Ü’ в кодировке Latin-1 и Unicode, 0xe9 указывает на ‘é’ в Латинской-1 и Unicode.

при работе с электронными устройствами кодовые точки Unicode должны быть представлены в электронном виде. Вот что такое схемы кодирования. Существуют различные схемы кодирования Юникода (utf7, UTF-8, UTF-16, UTF-32). Наиболее интуитивным и прямым подходом к кодированию было бы просто использовать значение кодовой точки На карте Unicode в качестве значения для ее электронной формы, но Unicode в настоящее время имеет более миллиона кодовых точек, что означает, что некоторые из них требуют 3 байта для выражения. Чтобы эффективно работать с текстом, сопоставление 1 к 1 было бы довольно непрактичным, поскольку для этого потребовалось бы, чтобы все кодовые точки хранились в точно таком же объеме пространства, как минимум 3 байта на символ, независимо от их фактической потребности.

большинство схем кодирования имеют недостатки в отношении требования к пространству, наиболее экономические из них не охватывают весь код unicode точки, например ascii охватывает только первые 128, в то время как латинский-1 охватывает первые 256. Другие, которые пытаются быть более всеобъемлющими, также оказываются расточительными, поскольку они требуют больше байтов, чем необходимо, даже для обычных «дешевых» символов. UTF-16, например, использует минимум 2 байта на символ, в том числе в диапазоне ascii («B», который равен 65, по-прежнему требует 2 байта хранения в UTF-16). UTF-32 еще более расточителен, поскольку он хранит все символы в 4 байтах.

UTF-8 случается, что умно разрешили дилемму, со схемой, способной хранить кодовые точки с переменным количеством байтовых пространств. В рамках своей стратегии кодирования UTF-8 laces кодирует точки с битами флага, которые указывают (предположительно для декодеров) их требования к пространству и их границы.

кодировка UTF-8 кодовых точек юникода в диапазоне ascii (0-127):

0xxx xxxx  (in binary)
  • x показывают фактическое пространство, зарезервированное для» хранения » кодовой точки во время кодировка
  • ведущим 0 является флаг, который указывает декодеру UTF-8, что для этой кодовой точки потребуется только 1 байт.
  • при кодировании UTF-8 не изменяет значение кодовых точек в этом конкретном диапазоне (т. е. 65, закодированный в UTF-8, также 65). Учитывая, что Unicode и ASCII также совместимы в одном диапазоне, это, кстати, делает UTF-8 и ASCII также совместимыми в этом диапазоне.

например, кодовая точка Юникода для » B » — «0x42» или 0100 0010 в двоичном формате (как мы уже говорили, это то же самое в ASCII). После кодирования в UTF-8 становится:

0xxx xxxx  <-- UTF-8 encoding for Unicode code points 0 to 127
*100 0010  <-- Unicode code point 0x42
0100 0010  <-- UTF-8 encoded (exactly the same)

UTF-8 кодировка Юникода кодовых точек выше 127 (non-ascii):

110x xxxx 10xx xxxx            <-- (from 128 to 2047)
1110 xxxx 10xx xxxx 10xx xxxx  <-- (from 2048 to 65535)
  • ведущие биты ‘ 110 ‘указывают декодеру UTF-8 начало кодовой точки, закодированной в 2 байтах, тогда как’ 1110 ‘ указывает на 3 байта, 11110 будет указывать на 4 байта и так далее.
  • внутренние биты флага ‘ 10 ‘ использованы для того чтобы сигнализировать начало внутренний байт.
  • опять же, x помечает пространство, в котором хранится значение кодовой точки Unicode после кодирования.

например, кодовая точка’ é ‘ Unicode равна 0xe9 (233).

1110 1001    <-- 0xe9

когда UTF-8 кодирует это значение, он определяет, что значение больше 127 и меньше 2048, поэтому должно быть закодировано в 2 байта:

110x xxxx 10xx xxxx   <-- UTF-8 encoding for Unicode 128-2047
***0 0011 **10 1001   <-- 0xe9
1100 0011 1010 1001   <-- 'é' after UTF-8 encoding
C    3    A    9

кодовые точки 0xe9 Unicode после кодировки UTF-8 становятся 0xc3a9. Именно так терминал получает он. Если ваш терминал настроен на декодирование строк с помощью latin-1 (одна из устаревших кодировок, отличных от unicode), вы увидите é, потому что так получилось, что 0xc3 в latin-1 указывает на à и 0xa9 на ©.

Сравнение кодировок Unicode — Comparison of Unicode encodings

В этой статье сравниваются кодировки Unicode . Рассмотрены две ситуации: среды с 8-битной чистотой и среды, которые запрещают использование байтовых значений с установленным старшим битом. Первоначально такие запреты были разрешены для ссылок, которые использовали только семь битов данных, но они остаются в стандартах, поэтому программное обеспечение должно генерировать сообщения, соответствующие ограничениям. Стандартная схема сжатия для Unicode и двоичное упорядоченное сжатие для Unicode исключены из сравнительных таблиц, потому что их размер сложно просто количественно определить.

Проблемы совместимости

UTF-8 файл , который содержит только ASCII символы идентичен файлу ASCII. Устаревшие программы обычно могут обрабатывать файлы в кодировке UTF-8, даже если они содержат символы, отличные от ASCII. Например, функция C printf может печатать строку UTF-8, поскольку она ищет только символ ASCII ‘%’ для определения строки форматирования и печатает все остальные байты без изменений, поэтому символы, отличные от ASCII, будут выводиться без изменений.

UTF-16 и UTF-32 несовместимы с файлами ASCII и поэтому требуют программ, поддерживающих Unicode, для отображения, печати и управления ими, даже если известно, что файл содержит только символы из подмножества ASCII. Поскольку они содержат много нулевых байтов, строками нельзя манипулировать обычной обработкой строк с завершающим нулем даже для простых операций, таких как копирование.

Поэтому даже в большинстве систем UTF-16, таких как Windows и Java , текстовые файлы UTF-16 встречаются нечасто; все еще используются старые 8-битные кодировки, такие как ASCII или ISO-8859-1 , без поддержки Unicode; или UTF-8 используется для Unicode. Одним из редких контрпримеров является «строковый» файл, используемый приложениями Mac OS X (10.3 и новее) для поиска интернационализированных версий сообщений, по умолчанию используется UTF-16, с «файлами, закодированными с использованием UTF-8 … не гарантируется работай.»

По умолчанию XML кодируется как UTF-8, и все процессоры XML должны как минимум поддерживать UTF-8 (включая US-ASCII по определению) и UTF-16.

Эффективность

UTF-8 требует 8, 16, 24 или 32 бита (от одного до четырех байтов ) для кодирования символа Unicode, UTF-16 требует 16 или 32 бит для кодирования символа, а UTF-32 всегда требует 32 бита для кодирования символа. . Первые 128 кодовых точек Unicode , от U + 0000 до U + 007F, используемые для элементов управления C0 и основных латинских символов и которые однозначно соответствуют их эквивалентам кода ASCII, кодируются с использованием 8 бит в UTF-8, 16 бит в UTF-16 и 32 бита в UTF-32. Следующие 1920 символов, от U + 0080 до U + 07FF (включая оставшуюся часть почти всех латинских алфавитов , а также греческий , кириллический , коптский , армянский , иврит , арабский , сирийский , тана и н’ко ), требуют 16 бит. для кодирования как в UTF-8, так и в UTF-16, и 32 бита в UTF-32. Для U + 0800 — U + FFFF, т. Е. Остаток символов в базовой многоязычной плоскости (BMP, плоскость 0, от U + 0000 до U + FFFF), которая включает в себя остальные символы большинства живых языков мира, UTF-8 требует 24 бита для кодирования символа, тогда как UTF-16 требует 16 бит, а UTF-32 требует 32. Кодовые точки от U + 010000 до U + 10FFFF, которые представляют символы в дополнительных плоскостях (плоскости 1–16), требуют 32 бита в UTF-8, UTF-16 и UTF-32. Все печатаемые символы в UTF-EBCDIC используют как минимум столько же байтов, сколько в UTF-8, и большинство из них используют больше, поскольку было принято решение разрешить кодирование управляющих кодов C1 как одиночных байтов. Для семибитных сред UTF-7 более эффективно использует пространство, чем комбинация других кодировок Unicode с цитируемой печатью или base64 почти для всех типов текста (см. « Семибитные среды » ниже).

Каждый формат имеет свой набор преимуществ и недостатков в отношении эффективности хранения (и, следовательно, времени передачи) и эффективности обработки. Эффективность хранения зависит от того места в кодовом пространстве Unicode, из которого преимущественно происходят любые заданные текстовые символы. Поскольку блоки кодового пространства Unicode организованы по набору символов (т. Е. По алфавиту / сценарию), эффективность хранения любого заданного текста эффективно зависит от алфавита / сценария, используемого для этого текста. Так, например, для UTF-8 требуется на один байт на символ меньше (8 против 16 бит), чем для UTF-16 для 128 кодовых точек между U + 0000 и U + 007F, но для каждого символа требуется на один байт больше (24 против 16 бит ) для 63 488 кодовых точек между U + 0800 и U + FFFF. Следовательно, если в диапазоне от U + 0000 до U + 007F больше символов, чем в диапазоне от U + 0800 до U + FFFF, тогда UTF-8 более эффективен, а если их меньше, то UTF-16 более эффективен. эффективный. Если счетчики равны, значит, они одинакового размера. Удивительным результатом является то, что реальные документы, написанные на языках, которые используют символы только в верхнем диапазоне, все еще часто короче в UTF-8 из-за широкого использования пробелов, цифр, знаков препинания, новой строки, разметки html и встроенных слов и аббревиатуры, написанные латинскими буквами.

Что касается времени обработки, текст с кодировкой переменной длины, такой как UTF-8 или UTF-16, труднее обрабатывать, если есть необходимость найти отдельные единицы кода, в отличие от работы с последовательностями единиц кода. На поиск не влияет то, имеют ли символы переменный размер, поскольку поиск последовательности кодовых единиц не заботится о делениях (он требует, чтобы кодировка была самосинхронизирующейся, что и UTF-8, и UTF-16). Распространенное заблуждение состоит в том, что существует необходимость «найти n- й символ» и что для этого требуется кодирование фиксированной длины; однако на практике число n получается только из проверки n-1 символов, поэтому в любом случае необходим последовательный доступ. UTF-16BE и UTF-32BE — с прямым порядком байтов , UTF-16LE и UTF-32LE — с прямым порядком байтов . Когда последовательности символов в одном порядке байтов загружаются на машину с другим порядком байтов, символы необходимо преобразовать, прежде чем их можно будет эффективно обрабатывать, если только данные не обрабатываются с байтовой гранулярностью (как требуется для UTF-8). Соответственно, рассматриваемая проблема больше относится к протоколу и связи, чем к вычислительной сложности.

Проблемы с обработкой

Для обработки формат должен быть простым для поиска, усечения и в целом безопасной обработки. Все нормальные кодировки Unicode используют некоторую форму кодовой единицы фиксированного размера. В зависимости от формата и кодовой точки, которая будет кодироваться, одна или несколько из этих кодовых единиц будут представлять кодовую точку Unicode . Для облегчения поиска и усечения последовательность не должна встречаться в более длинной последовательности или на границе двух других последовательностей. UTF-8, UTF-16, UTF-32 и UTF-EBCDIC имеют эти важные свойства, а UTF-7 и GB 18030 — нет.

Могут быть полезны символы фиксированного размера, но даже если существует фиксированное количество байтов на кодовую точку (как в UTF-32), фиксированного количества байтов на отображаемый символ не существует из-за комбинирования символов . Учитывая эти несовместимости и другие причуды между различными схемами кодирования, обработка данных Unicode с использованием одного и того же (или совместимого) протокола во всех интерфейсах и между интерфейсами (например, использование API / библиотеки, обработка символов Unicode в модели клиент / сервер и т. Д.) В целом может упростить весь конвейер, в то же время исключив потенциальный источник ошибок.

UTF-16 популярен, потому что многие API относятся ко времени, когда Unicode был 16-битной фиксированной шириной. Однако использование UTF-16 делает символы вне базовой многоязычной плоскости особым случаем, что увеличивает риск упущений, связанных с их обработкой. Тем не менее, программы, которые неправильно обрабатывают суррогатные пары, вероятно, также имеют проблемы с объединением последовательностей, поэтому использование UTF-32 вряд ли решит более общую проблему плохой обработки символов с несколькими кодовыми единицами.

Если какие-либо сохраненные данные находятся в UTF-8 (например, содержимое или имена файлов), очень сложно написать систему, которая использует UTF-16 или UTF-32 в качестве API. Это связано с часто упускаемым из виду фактом, что массив байтов, используемый UTF-8, может физически содержать недопустимые последовательности. Например, невозможно исправить недопустимое имя файла UTF-8 с помощью API UTF-16, так как никакая возможная строка UTF-16 не будет преобразована в это недопустимое имя файла. Обратное неверно: преобразовать недопустимый UTF-16 в уникальную (хотя технически недопустимую) строку UTF-8 — тривиально, поэтому API UTF-8 может управлять файлами и именами как UTF-8, так и UTF-16, что делает UTF -8 предпочтительнее в любой такой смешанной среде. Прискорбный, но гораздо более распространенный обходной путь, используемый системами UTF-16, — интерпретировать UTF-8 как некоторую другую кодировку, такую ​​как CP-1252, и игнорировать моджибаке для любых данных, отличных от ASCII.

Для связи и хранения

Для UTF-16 и UTF-32 не определен порядок байтов , поэтому необходимо выбирать порядок байтов при их получении по байтовой сети или чтении из байтового хранилища. Этого можно добиться, используя отметку порядка байтов в начале текста или предполагая прямой порядок байтов ( RFC 2781 ). UTF-8 , UTF-16BE , UTF-32BE , UTF-16LE и UTF-32LE стандартизированы в однобайтовом порядке и не имеют этой проблемы.

Если поток байтов подвержен повреждению, то некоторые кодировки восстанавливаются лучше, чем другие. UTF-8 и UTF-EBCDIC являются лучшими в этом отношении, поскольку они всегда могут повторно синхронизироваться после поврежденного или отсутствующего байта в начале следующей кодовой точки; GB 18030 не может быть восстановлен до следующего не числа ASCII. UTF-16 может обрабатывать измененные байты, но не нечетное количество пропущенных байтов, что приведет к искажению всего последующего текста (хотя и приведет к появлению необычных и / или неназначенных символов). Если биты могут быть потеряны, все они будут искажать следующий текст, хотя UTF-8 может быть повторно синхронизирован, поскольку неправильные границы байтов приведут к недопустимому UTF-8 в тексте, длина которого превышает несколько байтов.

В деталях

В таблицах ниже указано количество байтов на кодовую точку для разных диапазонов Unicode. Все необходимые дополнительные комментарии включены в таблицу. На рисунках предполагается, что накладные расходы в начале и в конце блока текста незначительны.

NB В таблицах ниже указано количество байтов на кодовую точку , а не на видимый пользователем «символ» (или «кластер графемы»). Для описания одного кластера графемы может потребоваться несколько кодовых точек, поэтому даже в UTF-32 необходимо соблюдать осторожность при разделении или объединении строк.

Восьмибитные среды

Кодовый диапазон (шестнадцатеричный)UTF-8UTF-16UTF-32UTF-EBCDIC ГБ 18030
000000–00007F12411
000080 — 00009F22 для символов, унаследованных от
GB 2312 / GBK (например, большинство
китайских символов) 4 для
всего остального.
0000A0 — 0003FF2
000400 — 0007FF3
000800 — 003FFF3
004000 — 00FFFF4
010000 — 03FFFF444
040000 — 10FFFF5

Семибитные среды

Эта таблица может не охватывать все особые случаи, поэтому ее следует использовать только для оценки и сравнения. Чтобы точно определить размер текста в кодировке, см. Фактические характеристики.

Кодовый диапазон (шестнадцатеричный)UTF-7UTF-8 в кавычках — для
печати
UTF-8 base64UTF-16 q.-p.UTF-16 base64GB 18030 q.-p.ГБ 18030 base64
Графические символы ASCII
(кроме U + 003D «=»)
1 для «прямых символов» (зависит от настройки кодировщика для некоторых кодовых точек), 2 для U + 002B «+», в остальном то же, что и для 000080 — 00FFFF1​1 13 4​2 23 1​1 13 
00003D (знак равенства)363
Управляющие символы ASCII :
000000 — 00001F
и 00007F
1 или 3 в зависимости от прямоты1 или 3 в зависимости от прямоты
000080 — 0007FF5 для отдельного случая внутри серии однобайтовых символов. Для прогонов 2 2 / 3  на символ плюс дополнения , чтобы сделать это целое число байтов плюс два , чтобы начать и закончить бег6​2 23 2–6 в зависимости от того, нужно ли экранировать байтовые значения4–6 для символов, унаследованных от GB2312 / GBK (например,
большинство китайских символов) 8 для всего остального.
​2 2 / +3  для персонажей , унаследованных от GB2312 / ГБК (например ,
большинство китайских символов) 5 1 / 3  для всего остального.
000800 — 00FFFF94
010000 — 10FFFF8 для изолированного случая, 5 1 / 3  на символ плюс дополнение к целому числу плюс 2 для бега12​5 13 8–12 в зависимости от того, нужно ли экранировать младшие байты суррогатов.​5 13 8​5 13 

Порядок байтов не влияет на размеры ( UTF-16BE и UTF-32BE имеют тот же размер, что и UTF-16LE и UTF-32LE , соответственно). Использование UTF-32 в кавычках крайне непрактично, но в случае реализации приведет к 8–12 байтам на кодовую точку (примерно 10 байтов в среднем), а именно для BMP каждая кодовая точка будет занимать ровно на 6 байтов больше, чем тот же код в quoted-printable / UTF-16. Base64 / UTF-32 получает 5 +1 / 3  байта для любой точки коды.

Управляющий символ ASCII в кавычках-печатных или UTF-7 может быть представлен либо напрямую, либо закодирован (экранирован). Необходимость экранировать данный управляющий символ зависит от многих обстоятельств, но новые строки в текстовых данных обычно кодируются напрямую.

Схемы сжатия

BOCU-1 и ГТС два способ сжатия данных Unicode. Их кодировка зависит от того, как часто используется текст. В большинстве серий текста используется один и тот же сценарий; например, латиница , кириллица , греческий и так далее. Это нормальное использование позволяет сжать несколько строк текста примерно до 1 байта на кодовую точку. Эти кодировки с отслеживанием состояния затрудняют произвольный доступ к тексту в любой позиции строки.

Эти две схемы сжатия не так эффективны, как другие схемы сжатия, такие как zip или bzip2 . Эти схемы сжатия общего назначения могут сжимать более длинные серии байтов до нескольких байтов. В SCSU и BOCU-1 схемы сжатия не будет сжимать больше , чем 25% теоретического текста в кодировке UTF-8, UTF-16 или UTF-32. Другие схемы сжатия общего назначения могут легко сжать до 10% исходного размера текста. Схемы общего назначения требуют более сложных алгоритмов и более длинных фрагментов текста для хорошей степени сжатия.

Техническая записка Unicode № 14 содержит более подробное сравнение схем сжатия.

Исторический: UTF-5 и UTF-6

Были сделаны предложения по UTF-5 и UTF-6 для интернационализации доменных имен (IDN). Предложение UTF-5 использовало кодировку base 32 , где Punycode (помимо прочего, но не совсем) является кодировкой base 36 . Название UTF-5 для 5-битной кодовой единицы объясняется уравнением 2 5 = 32. Предложение UTF-6 добавило кодировку текущей длины к UTF-5, здесь 6 просто означает UTF-5 плюс 1 . IETF IDN WG позже принял более эффективный Punycode для этой цели.

Не преследуется серьезно

UTF-1 так и не получил серьезного признания. UTF-8 используется гораздо чаще.

UTF-9 и UTF-18 , несмотря на то, что они были функциональными кодировками, были спецификациями шутки RFC Первого апреля .

Ссылки

Unicode, ASCII, KOI и прочее зверьё. – Delphi в Internet

Буквально на днях снова пришлось возвратиться к теме о клавиатурных шпионах, виртуальных и скан-кодах клавиш и прочей работе с клавой.

Признаться до этого момента я до конца себе не представлял, что за проблемы стоят перед разработчиками, которые пишут, например редакторы с автоматическим переключением кодировок, да даже не кодировок – просто раскладок! До сих пор, имея под рукой дорожайшую и всеми (ну или большинством любимую) Delphi 7, можно было без особых проволочек и напрягов накидать небольшого клавиатурного шпиончика или просто программку, считывающую виртуальные коды клавиш. Но в Delphi 2009-2010 заявили Unicode. Идея безусловно отличная, я бы даже сказал, крайне необходимая в современных условиях, но как оказалось воплощение этой идеи было не самым удачным. О чем собственно и заявляли не раз в своих блогах программисты, пробующие перевести свои проекты из Delphi 7 в Delphi 2009.  И вот теперь, когда кругом Unicode, посмотрим какая собственно проблема возникает? 

Так как тема поста заявлена довольно широкая, то видимо рассуждения и примеры придётся расписывать на несколько частей. И начать бы стоит с самого интересного, на мой взгляд, вопроса – истории кодировок в принципе.   Узнаем историю – в дальнейшем при разработке будет меньше возникать вопросов типа “А почему так?” Которые, кстати я себе не раз задавал, пока разобрался, что и к чему относиться. Итак, история кодировок.

1. Первые кодировки символов

Как дать понять груде железа под названием компьютер, что перед ним некий конкретный язык? Да ещё и сделать так, что бы он подставил в нужные места нужные символы?

Решение этой задачи оказывается известно давным-давно, ещё со времен слепого французского врача Луи Брайля (1809-1852 гг.) , который ещё будучи мальчиком в коротких штанишках, придумал последовательную систему рельефных точек, кодирующих буквы алфавита, цифры и знаки препинания для слепых – несколько дополненная азбука Брайля используется и в наши дни.

Базовый элемент системы Брайля содержит шесть позиция-ячеек, каждая из которых может быть выпуклой или плоской, т.е., проведя простейшую математическую операцию можно сказать, что всего в азбуке Брайля было закодировано 2^6 = 64 символа (видали, когда ещё двоичную системы во всю юзали?), однако Брайлем предусмотрен интересный механизм практически неограниченного расширения количества кодируемых символов. Для этого употребляются специальные коды-переключатели (Shift-коды). Наличие такого переключателя может, например, свидетельствовать, что все последующие знаки – это цифры, а не буквы и т.д., до тех пор пока не встретится другой подобный знак (не напоминает аналоги. с HTML?). Другая разновидность переключателей (Escape-кодов) действует только на один знак после такого кода, и тоже впервые введена в азбуке Брайля.

Теперь можете провести небольшую аналогию с современной клавиатурой:  Shift-код – очень напоминает включенный CapsLook, а Escape-код – зажатый шифт. Конечно, сказать о том, что Брайль был настолько суров, что разработал кодовую таблицу для первых компьютеров – верх глупости, но тем не менее, разработанная им система кодирования, хоть и в сильно измененном виде, но используется по сей день в современных ЭВМ.

Несмотря на это, предшественником современных компьютерных кодировок принято считать коды,  разработанные в 1874 году Эмилем Бодо, усовершенствованные позднее Дональдом Мюрреем и принятые в качестве международного стандарта в 1931 году. Официальное название кода Бодо – International Telegraph Alpabet #2, ITA-2. Он применялся в телетайпных аппаратах и, соответственно в первых компьютерах.

КодыБодо – пятибитовые, поэтому количество представленных символов ограничено 32, чего для всех необходимых символов не хватает. Для увеличения этого числа использовались опять же Shift-переключатели. Основная проблема заключалась в том, что Shift-переключатель действовал до тех пор, пока не встречался другой переключатель, отменяющий предыдущий. Поэтому, если какое-либо предложение заканчивалось цифрой, то следующее за ним предложение представляло собой бессмысленный надор цифр до тех пор пока не встречался очередной Shift-переключатель.

В 1963 году возник, а в 1967 году утвержден в качестве стандарта American Standard Code for Information InterchandgeASCII, который и является по сей день основой всех кодовых таблиц, устанавливая символы с номерами 0-127 (а точнее, 32-127, т. к. до 32 символа располагаются команды и могут интерпретироваться по разному). У истоков ASCII стояла фирма AT&T, а также IBM.

Русские разработчики кодовых таблиц тоже не остались в стороне и в середине 70-х годов возникла KOI, в которой русские буквы во второй половине таблицы ставились на такие места, чтобы при вычитании числа 128 из кода получалась соответствующая по звучанию английская буква, причем в противоположном регистре, чтобы отличить русский текст от английского. Так, например, строка “Привет” превратилась бы в “pRIVET”. Сделано это было потому, что первые почтовые серверы были семидитовыми, т.е. могли передавать только ASCII. KOI-8 существовала в виде общесоюзного стандарта и даже чуть не была утверждена в качестве международного, но “чуть” не считается.

Время шло,  компьютерное дело расширялось, и в нашей стране и в родственных странах была разработана масса кодировок: украинская, болгарская, польская и пр. Среди них наибольшую известность получили “основная” (ISO/IEC 8859-5-88) и “альтернативная”  (MS-DOS, CP866). Как мы теперь уже знаем, прочное место в наших первых “персоналках” заняла именно “альтернативная кодировка”, а “основная” канула в небытие.

CP866 едва ли не самая продуманная из существующих кодовых таблиц – в ней предусмотрительно были сохранены все положения символов из ASCII, в результате чего, английский текст выглядел абсолютно читабельным при любой кодировке страницы.

И тут в историю семимильными шагами входит корпорация Microsoft…

2. Кодировки эпохи Windows

С развитием Windows разработчики придумали ещё одну кодировку, как обычно забив болт на все национальные стандарты и традиции (а собственно зачем их учитывать, если США – это пуп Земли?). Её создатели логично рассудили, что символы псевдографики при наличии графических редакторов (в т.ч. и от Microsoft) как-то особенно никому не нужны. Кириллическая азбука заняла почётные последние 64 ячейки, кроме, почему-то букв “Ё” и “е”. Новая кодировка получила опять же логичное название – Windows 1251 (Win1251), которая и по сей день используется и ещё долго будет использоваться, в т.ч. и веб-мастерами.

Что самое примечательное, так это то, что внедрением и СР866 и Win1251 в 1995 году занимался один и тот же человек – россиянин Петр Квитек.

На самом деле на сегодняшний день действуют параллельно пять однобайтовых кириллических кодировок, с которыми мы постараемся познакомиться в будущем.

Вот теперь посмотрим – как же была решена проблема кодировок в международном отношении?

Unicode

Введение двухбайтной кодировки было задумано хорошо, а выполнено как обычно через…короче “как всегда”. Разработчики Microsoft зачем-то разделили понятие “языка” и “раскладки”. Зачем? Ведь отображение шрифта на экране однозначно определяется кодовой страницей, а при вводе – раскладкой. Чего за “язык” такой? Все дело в том, что таким образом разработчики Microsoft пытались обеспечить поддержку многоязычных документов и  даже в чем-то преуспели.

Теперь непосредственно про Unicode. Вообще двухбайтный Unicode ASCII организован элементарно просто и логично: если первый байт равен нулю, то второй соответствует начертанию символа из таблицы (или, что тоже самое, английскому языку). Если же первый байт равен, например 4, то следующий байт представляет собой символ из кириллицы и т.д. Русские буквы в таблице располагаются подряд, начиная со значения младшего байта, равного 16. Ну а буквы “Ё” и “е” как обычно – отдельно. Всякие скобки, тире выбираются из отдельных таблиц со своим значением первого байта.

Логично составлена таблица? По-моему вполне – здесь и сохранение ASCII и четко продуманная структура – взял старший байт – определил что за язык. Но, как и в любой бочке меда, нашлась своя ложка дёгтя.

Unicode и Win32

Чтобы не утомлять Вас лишними примерами из прошлого Windows, но, тем не менее понять “глючность”  использования unicode в win32, вспомните или воспроизведите такой простой пример. Откройте Word и наберите там какой-нибуль кусок кода с комментариями на русском, а потом вставьте этот кусок текста в Delphi 7. Что окажется на месте русских букв? Правильно “кракозябры”. А почему? Не потому, что ubicode не доработан – там все логично и понятно, а потому, что разработчики Windows перестарались при разработке новых версий операционной системы. И теперь разработчикам приходится долго и упорно карпеть над программным обеспечением, способным “на лету” схватывать кодировки символов и правильно их выводить на экран.

Ну, а как это делается в Delphi мы рассмотрим с Вам в следующей части статьи,  в которой мы затронем вопрос определения виртуального кода клавиши и попробуем связать воедино виртуальный код и unicode.

0
0
голос

Рейтинг статьи

Кодировка текста ASCII (Windows 1251, CP866, KOI8-R) и Юникод (UTF 8, 16, 32) — как исправить проблему с кракозябрами

Сегодня мы поговорим с вами про то, откуда берутся кракозябры на сайте и в программах, какие кодировки текста существуют и какие из них следует использовать. Подробно рассмотрим историю их развития, начиная от базовой ASCII, а также ее расширенных версий CP866, KOI8-R, Windows 1251 и заканчивая современными кодировками консорциума Юникод UTF 16 и 8.

Оглавление:
Кому-то эти сведения могут показаться излишними, но знали бы вы, сколько мне приходит вопросов именно касаемо вылезших кракозябров (не читаемого набора символов). Теперь у меня будет возможность отсылать всех к тексту этой статьи и самостоятельно отыскивать свои косяки. Ну что же, приготовьтесь впитывать информацию и постарайтесь следить за ходом повествования.

ASCII — базовая кодировка текста для латиницы

Развитие кодировок текстов происходило одновременно с формированием отрасли IT, и они за это время успели претерпеть достаточно много изменений. Исторически все начиналось с довольно-таки не благозвучной в русском произношении EBCDIC, которая позволяла кодировать буквы латинского алфавита, арабские цифры и знаки пунктуации с управляющими символами.

Но все же отправной точкой для развития современных кодировок текстов стоит считать знаменитую ASCII (American Standard Code for Information Interchange, которая по-русски обычно произносится как «аски»). Она описывает первые 128 символов из наиболее часто используемых англоязычными пользователями — латинские буквы, арабские цифры и знаки препинания.

Еще в эти 128 знаков, описанных в ASCII, попадали некоторые служебные символы навроде скобок, решеток, звездочек и т.п. Собственно, вы сами можете увидеть их:
Именно эти 128 символов из первоначального вариант ASCII стали стандартом, и в любой другой кодировке вы их обязательно встретите и стоять они будут именно в таком порядке.

Но дело в том, что с помощью одного байта информации можно закодировать не 128, а целых 256 различных значений (двойка в степени восемь равняется 256), поэтому вслед за базовой версией Аски появился целый ряд расширенных кодировок ASCII, в которых можно было кроме 128 основных знаков закодировать еще и символы национальной кодировки (например, русской).

Тут, наверное, стоит еще немного сказать про системы счисления, которые используются при описании. Во-первых, как вы все знаете, компьютер работает только с числами в двоичной системе, а именно с нулями и единицами («булева алгебра», если кто проходил в институте или в школе). Один байт состоит из восьми бит, каждый из которых представляет из себя двойку в степени, начиная с нулевой, и до двойки в седьмой:

Не трудно понять, что всех возможных комбинаций нулей и единиц в такой конструкции может быть только 256. Переводить число из двоичной системы в десятичную довольно просто. Нужно просто сложить все степени двойки, над которыми стоят единички.

В нашем примере это получается 1 (2 в степени ноль) плюс 8 (два в степени 3), плюс 32 (двойка в пятой степени), плюс 64 (в шестой), плюс 128 (в седьмой). Итого получает 233 в десятичной системе счисления. Как видите, все очень просто.

Но если вы присмотритесь к таблице с символами ASCII, то увидите, что они представлены в шестнадцатеричной кодировке. Например, «звездочка» соответствует в Аски шестнадцатеричному числу 2A. Наверное, вам известно, что в шестнадцатеричной системе счисления используются кроме арабских цифр еще и латинские буквы от A (означает десять) до F (означает пятнадцать).

Ну так вот, для перевода двоичного числа в шестнадцатеричное прибегают к следующему простому и наглядному способу. Каждый байт информации разбивают на две части по четыре бита, как показано на приведенном выше скриншоте. Т.о. в каждой половинке байта двоичным кодом можно закодировать только шестнадцать значений (два в четвертой степени), что можно легко представить шестнадцатеричным числом.

Причем, в левой половине байта считать степени нужно будет опять начиная с нулевой, а не так, как показано на скриншоте. В результате, путем нехитрых вычислений, мы получим, что на скриншоте закодировано число E9. Надеюсь, что ход моих рассуждений и разгадка данного ребуса вам оказались понятны. Ну, а теперь продолжим, собственно, говорить про кодировки текста.

Расширенные версии Аски — кодировки CP866 и KOI8-R с псевдографикой

Итак, мы с вами начали говорить про ASCII, которая являлась как бы отправной точкой для развития всех современных кодировок (Windows 1251, юникод, UTF 8).

Изначально в нее было заложено только 128 знаков латинского алфавита, арабских цифр и еще чего-то там, но в расширенной версии появилась возможность использовать все 256 значений, которые можно закодировать в одном байте информации. Т.е. появилась возможность добавить в Аски символы букв своего языка.

Тут нужно будет еще раз отвлечься, чтобы пояснить — зачем вообще нужны кодировки текстов и почему это так важно. Символы на экране вашего компьютера формируются на основе двух вещей — наборов векторных форм (представлений) всевозможных знаков (они находятся в файлах со шрифтами, которые установлены на вашем компьютере) и кода, который позволяет выдернуть из этого набора векторных форм (файла шрифта) именно тот символ, который нужно будет вставить в нужное место.

Понятно, что за сами векторные формы отвечают шрифты, а вот за кодирование отвечает операционная система и используемые в ней программы. Т.е. любой текст на вашем компьютере будет представлять собой набор байтов, в каждом из которых закодирован один единственный символ этого самого текста.

Программа, отображающая этот текст на экране (текстовый редактор, браузер и т.п.), при разборе кода считывает кодировку очередного знака и ищет соответствующую ему векторную форму в нужном файле шрифта, который подключен для отображения данного текстового документа. Все просто и банально.

Значит, чтобы закодировать любой нужный нам символ (например, из национального алфавита), должно быть выполнено два условия — векторная форма этого знака должна быть в используемом шрифте и этот символ можно было бы закодировать в расширенных кодировках ASCII в один байт. Поэтому таких вариантов существует целая куча. Только лишь для кодирования символов русского языка существует несколько разновидностей расширенной Аски.

Например, изначально появилась CP866, в которой была возможность использовать символы русского алфавита и она являлась расширенной версией ASCII.

Т.е. ее верхняя часть полностью совпадала с базовой версией Аски (128 символов латиницы, цифр и еще всякой лабуды), которая представлена на приведенном чуть выше скриншоте, а вот уже нижняя часть таблицы с кодировкой CP866 имела указанный на скриншоте чуть ниже вид и позволяла закодировать еще 128 знаков (русские буквы и всякая там псевдографика):

Видите, в правом столбце цифры начинаются с 8, т.к. числа с 0 до 7 относятся к базовой части ASCII (см. первый скриншот). Т.о. русская буква «М» в CP866 будет иметь код 9С (она находится на пересечении соответствующих строки с 9 и столбца с цифрой С в шестнадцатеричной системе счисления), который можно записать в одном байте информации, и при наличии подходящего шрифта с русскими символами эта буква без проблем отобразится в тексте.

Откуда взялось такое количество псевдографики в CP866? Тут все дело в том, что эта кодировка для русского текста разрабатывалась еще в те мохнатые года, когда не было такого распространения графических операционных систем как сейчас. А в Досе, и подобных ей текстовых операционках, псевдографика позволяла хоть как-то разнообразить оформление текстов и поэтому ею изобилует CP866 и все другие ее ровесницы из разряда расширенных версий Аски.

CP866 распространяла компания IBM, но кроме этого для символов русского языка были разработаны еще ряд кодировок, например, к этому же типу (расширенных ASCII) можно отнести KOI8-R:
Принцип ее работы остался тот же самый, что и у описанной чуть ранее CP866 — каждый символ текста кодируется одним единственным байтом. На скриншоте показана вторая половина таблицы KOI8-R, т.к. первая половина полностью соответствует базовой Аски, которая показана на первом скриншоте в этой статье.

Среди особенностей кодировки KOI8-R можно отметить то, что русские буквы в ее таблице идут не в алфавитном порядке, как это, например, сделали в CP866.

Если посмотрите на самый первый скриншот (базовой части, которая входит во все расширенные кодировки), то заметите, что в KOI8-R русские буквы расположены в тех же ячейках таблицы, что и созвучные им буквы латинского алфавита из первой части таблицы. Это было сделано для удобства перехода с русских символов на латинские путем отбрасывания всего одного бита (два в седьмой степени или 128).

Windows 1251 — современная версия ASCII и почему вылезают кракозябры

Дальнейшее развитие кодировок текста было связано с тем, что набирали популярность графические операционные системы и необходимость использования псевдографики в них со временем пропала. В результате возникла целая группа, которая по своей сути по-прежнему являлись расширенными версиями Аски (один символ текста кодируется всего одним байтом информации), но уже без использования символов псевдографики.

Они относились к так называемым ANSI кодировкам, которые были разработаны американским институтом стандартизации. В просторечии еще использовалось название кириллица для варианта с поддержкой русского языка. Примером такой может служить Windows 1251.

Она выгодно отличалась от используемых ранее CP866 и KOI8-R тем, что место символов псевдографики в ней заняли недостающие символы русской типографики (окромя знака ударения), а также символы, используемые в близких к русскому славянских языках (украинскому, белорусскому и т.д.):
Из-за такого обилия кодировок русского языка, у производителей шрифтов и производителей программного обеспечения постоянно возникала головная боль, а у нас с вам, уважаемые читатели, зачастую вылезали те самые пресловутые кракозябры, когда происходила путаница с используемой в тексте версией.

Очень часто они вылезали при отправке и получении сообщений по электронной почте, что повлекло за собой создание очень сложных перекодировочных таблиц, которые, собственно, решить эту проблему в корне не смогли, и зачастую пользователи для переписки использовали транслит латинских букв, чтобы избежать пресловутых кракозябров при использовании русских кодировок подобных CP866, KOI8-R или Windows 1251.

По сути, кракозябры, вылазящие вместо русского текста, были результатом некорректного использования кодировки данного языка, которая не соответствовала той, в которой было закодировано текстовое сообщение изначально.

Допустим, если символы, закодированные с помощью CP866, попробовать отобразить, используя кодовую таблицу Windows 1251, то эти самые кракозябры (бессмысленный набор знаков) и вылезут, полностью заменив собой текст сообщения.
Аналогичная ситуация очень часто возникает при создании и настройке сайтов, форумов или блогов, когда текст с русскими символами по ошибке сохраняется не в той кодировке, которая используется на сайте по умолчанию, или же не в том текстовом редакторе, который добавляет в код отсебятину не видимую невооруженным глазом.

В конце концов такая ситуация с множеством кодировок и постоянно вылезающими кракозябрами многим надоела, появились предпосылки к созданию новой универсальной вариации, которая бы заменила собой все существующие и решила бы, наконец, на корню проблему с появлением не читаемых текстов. Кроме этого существовала проблема языков подобных китайскому, где символов языка было гораздо больше, чем 256.

Юникод (Unicode) — универсальные кодировки UTF 8, 16 и 32

Эти тысячи знаков языковой группы юго-восточной Азии никак невозможно было описать в одном байте информации, который выделялся для кодирования символов в расширенных версиях ASCII. В результате был создан консорциум под названием Юникод (Unicode — Unicode Consortium) при сотрудничестве многих лидеров IT индустрии (те, кто производит софт, кто кодирует железо, кто создает шрифты), которые были заинтересованы в появлении универсальной кодировки текста.

Первой вариацией, вышедшей под эгидой консорциума Юникод, была UTF 32. Цифра в названии кодировки означает количество бит, которое используется для кодирования одного символа. 32 бита составляют 4 байта информации, которые понадобятся для кодирования одного единственного знака в новой универсальной кодировке UTF.

В результате чего, один и тот же файл с текстом, закодированный в расширенной версии ASCII и в UTF-32, в последнем случае будет иметь размер (весить) в четыре раза больше. Это плохо, но зато теперь у нас появилась возможность закодировать с помощью ЮТФ число знаков, равное двум в тридцать второй степени (миллиарды символов, которые покроют любое реально необходимое значение с колоссальным запасом).

Но многим странам с языками европейской группы такое огромное количество знаков использовать в кодировке вовсе и не было необходимости, однако при задействовании UTF-32 они ни за что ни про что получали четырехкратное увеличение веса текстовых документов, а в результате и увеличение объема интернет трафика и объема хранимых данных. Это много, и такое расточительство себе никто не мог позволить.

В результате развития Юникода появилась UTF-16, которая получилась настолько удачной, что была принята по умолчанию как базовое пространство для всех символов, которые у нас используются. Она использует два байта для кодирования одного знака. Давайте посмотрим, как это дело выглядит.

В операционной системе Windows вы можете пройти по пути «Пуск» — «Программы» — «Стандартные» — «Служебные» — «Таблица символов». В результате откроется таблица с векторными формами всех установленных у вас в системе шрифтов. Если вы выберете в «Дополнительных параметрах» набор знаков Юникод, то сможете увидеть для каждого шрифта в отдельности весь ассортимент входящих в него символов.

Кстати, щелкнув по любому из них, вы сможете увидеть его двухбайтовый код в формате UTF-16, состоящий из четырех шестнадцатеричных цифр:
Сколько символов можно закодировать в UTF-16 с помощью 16 бит? 65 536 (два в степени шестнадцать), и именно это число было принято за базовое пространство в Юникоде. Помимо этого существуют способы закодировать с помощью нее и около двух миллионов знаков, но ограничились расширенным пространством в миллион символов текста.

Но даже эта удачная версия кодировки Юникода не принесла особого удовлетворения тем, кто писал, допустим, программы только на английском языке, ибо у них, после перехода от расширенной версии ASCII к UTF-16, вес документов увеличивался в два раза (один байт на один символ в Аски и два байта на тот же самый символ в ЮТФ-16).

Вот именно для удовлетворения всех и вся в консорциуме Unicode было решено придумать кодировку переменной длины. Ее назвали UTF-8. Несмотря на восьмерку в названии, она действительно имеет переменную длину, т.е. каждый символ текста может быть закодирован в последовательность длиной от одного до шести байт.

На практике же в UTF-8 используется только диапазон от одного до четырех байт, потому что за четырьмя байтами кода ничего уже даже теоретически не возможно представить. Все латинские знаки в ней кодируются в один байт, так же как и в старой доброй ASCII.

Что примечательно, в случае кодирования только латиницы, даже те программы, которые не понимают Юникод, все равно прочитают то, что закодировано в ЮТФ-8. Т.е. базовая часть Аски просто перешла в это детище консорциума Unicode.

Кириллические же знаки в UTF-8 кодируются в два байта, а, например, грузинские — в три байта. Консорциум Юникод после создания UTF 16 и 8 решил основную проблему — теперь у нас в шрифтах существует единое кодовое пространство. И теперь их производителям остается только исходя из своих сил и возможностей заполнять его векторными формами символов текста.

В приведенной чуть выше «Таблице символов» видно, что разные шрифты поддерживают разное количество знаков. Некоторые насыщенные символами Юникода шрифты могут весить очень прилично. Но зато теперь они отличаются не тем, что они созданы для разных кодировок, а тем, что производитель шрифта заполнил или не заполнил единое кодовое пространство теми или иными векторными формами до конца.

Кракозябры вместо русских букв — как исправить

Давайте теперь посмотрим, как появляются вместо текста кракозябры или, другими словами, как выбирается правильная кодировка для русского текста. Собственно, она задается в той программе, в которой вы создаете или редактируете этот самый текст, или же код с использованием текстовых фрагментов.

Для редактирования и создания текстовых файлов лично я использую очень хороший, на мой взгляд, Html и PHP редактор Notepad++. Впрочем, он может подсвечивать синтаксис еще доброй сотни языков программирования и разметки, а также имеет возможность расширения с помощью плагинов. Читайте подробный обзор этой замечательной программы по приведенной ссылке.

В верхнем меню Notepad++ есть пункт «Кодировки», где у вас будет возможность преобразовать уже имеющийся вариант в тот, который используется на вашем сайте по умолчанию:
В случае сайта на Joomla 1.5 и выше, а также в случае блога на WordPress следует во избежании появления кракозябров выбирать вариант UTF 8 без BOM. А что такое приставка BOM?

Дело в том, что когда разрабатывали кодировку ЮТФ-16, зачем-то решили прикрутить к ней такую вещь, как возможность записывать код символа, как в прямой последовательности (например, 0A15), так и в обратной (150A). А для того, чтобы программы понимали, в какой именно последовательности читать коды, и был придуман BOM (Byte Order Mark или, другими словами, сигнатура), которая выражалась в добавлении трех дополнительных байтов в самое начало документов.

В кодировке UTF-8 никаких BOM предусмотрено в консорциуме Юникод не было и поэтому добавление сигнатуры (этих самых пресловутых дополнительных трех байтов в начало документа) некоторым программам просто-напросто мешает читать код. Поэтому мы всегда при сохранении файлов в ЮТФ должны выбирать вариант без BOM (без сигнатуры). Таким образом, вы заранее обезопасите себя от вылезания кракозябров.

Что примечательно, некоторые программы в Windows не умеют этого делать (не умеют сохранять текст в ЮТФ-8 без BOM), например, все тот же пресловутый Блокнот Windows. Он сохраняет документ в UTF-8, но все равно добавляет в его начало сигнатуру (три дополнительных байта). Причем эти байты будут всегда одни и те же — читать код в прямой последовательности. Но на серверах из-за этой мелочи может возникнуть проблема — вылезут кракозябры.

Поэтому ни в коем случае не пользуйтесь обычным блокнотом Windows для редактирования документов вашего сайта, если не хотите появления кракозябров. Лучшим и наиболее простым вариантом я считаю уже упомянутый редактор Notepad++, который практически не имеет недостатков и состоит из одних лишь достоинств.

В Notepad ++ при выборе кодировки у вас будет возможность преобразовать текст в кодировку UCS-2, которая по своей сути очень близка к стандарту Юникод. Также в Нотепаде можно будет закодировать текст в ANSI, т.е. применительно к русскому языку это будет уже описанная нами чуть выше Windows 1251. Откуда берется эта информация?

Она прописана в реестре вашей операционной системы Windows — какую кодировку выбирать в случае ANSI, какую выбирать в случае OEM (для русского языка это будет CP866). Если вы установите на своем компьютере другой язык по умолчанию, то и эти кодировки будут заменены на аналогичные из разряда ANSI или OEM для того самого языка.

После того, как вы в Notepad++ сохраните документ в нужной вам кодировке или же откроете документ с сайта для редактирования, то в правом нижнем углу редактора сможете увидеть ее название:
Чтобы избежать кракозябров, кроме описанных выше действий, будет полезным прописать в его шапке исходного кода всех страниц сайта информацию об этой самой кодировке, чтобы на сервере или локальном хосте не возникло путаницы.

Вообще, во всех языках гипертекстовой разметки кроме Html используется специальное объявление xml, в котором указывается кодировка текста.


<?xml version="1.0" encoding="windows-1251"?>

Прежде, чем начать разбирать код, браузер узнает, какая версия используется и как именно нужно интерпретировать коды символов этого языка. Но что примечательно, в случае, если вы сохраняете документ в принятом по умолчанию юникоде, то это объявление xml можно будет опустить (кодировка будет считаться UTF-8, если нет BOM или ЮТФ-16, если BOM есть).

В случае же документа языка Html для указания кодировки используется элемент Meta, который прописывается между открывающим и закрывающим тегом Head:


<head>
...
<meta charset="utf-8">
...
</head>

Эта запись довольно сильно отличается от принятой в стандарте в Html 4.01, но полностью соответствует новому внедряемому потихоньку стандарту Html 5, и она будет стопроцентно правильно понята любыми используемыми на текущий момент браузерами.

По идее, элемент Meta с указание кодировки Html документа лучше будет ставить как можно выше в шапке документа, чтобы на момент встречи в тексте первого знака не из базовой ANSI (которые правильно прочитаются всегда и в любой вариации) браузер уже должен иметь информацию о том, как интерпретировать коды этих символов.

Ссылка на первоисточник: Кодировка текста ASCII (Windows 1251, CP866, KOI8-R) и Юникод (UTF 8, 16, 32) — как исправить проблему с кракозябрами

Таблицы кодов символов ascii и unicode

Каждый компьютер имеет свой набор символов, который он реализует. Такой набор содержит 26 заглавных и строчных букв, цифры и специальные символы (точка, пробел и тд). Символы при переводе в целые числа имеют название кодами. Были разработаны стандарты, что бы компьютеры имели одинаковые наборы кодов.

Стандарт ASCII

ASCII (American Standart Code for Inmormation Interchange) — американский стандартный код для обмена информацией. Каждый символ ASCII имеет 7 битов, поэтому максимальное число символов — 128 (таблица 1). Коды от 0 до 1F являются управляющими символами, которые не печатаются. Множество непечатных символов ASCII нужны для передачи данных. К примеру послание может состоять из символа начала заголовка SOH, самого заголовка и символа начала текста STX, самого текста и символа конца текста ETX, и символ конца передачи EOT. Однако данные по сети передаются в пакетах, которые сами отвечают за начало передачи и конец. Так что непечатные символы почти не используются.

Таблица 1 — таблица кодов ASCII

ЧислоКомандаЗначениеЧислоКомандаЗначение
0NULПустой указатель10DLEВыход из системы передачи
1SOHначало заголовка11DC1Управление устройством
2STXНачало текста12DC2Управление устройством
3ETXКонец текста13DC3Управление устройством
4EOTКонец передачи14DC4Управление устройством
5ACKЗапрос15NAKНеподтверждение приема
6BELПодтверждение приема16SYNПростой
7BSСимвол звонка17ETBКонец блока передачи
8HTОтступ назад18CANОтмета
9LFГоризонтальная табуляция19EMКонец носителя
AVTПеревод строки1ASUBПодстрочный индекс
BFFВертикальная табуляция1BESCВыход
CCRПеревод страницы1CFSРазделитель файлов
DSOВозврат каретки1DGSРазделитель группы
ESIПереключение на дополнительный регистр1ERSРазделитель записи
SIПереключение на стандартный регистр1FUSРазделитель модуля
ЧислоСимволЧислоСимволЧислоСимволЧислоСимволЧислоСимволЧислоСимвол
20пробел30040@50P60.70p
21!31141A51Q61a71q
2232242B52R62b72r
23#33343C53S63c73s
24φ34444D54T64d74t
25%35545E55И65e75и
26&36646F56V66f76v
2737747G57W67g77w
28(38848H58X68h78x
29)39949I59Y69i70y
2A3A;4AJ5AZ6Aj7Az
2B+3B;4BK5B[6Bk7B{
2C3C<4CL5C\6Cl7C|
2D3D=4DM5D]6Dm7D}
2E3E>4EN5E6En7E~
2F/3Fg4FO5F_6Fo7FDEL

Стандарт Unicode

Предыдущая кодировка отлично подходит для английского языка, однако для других языков она не удобная. К примеру в немецком языке есть умляуты, а в французском надстрочные знаки. Некоторые языки имеют совершенно разные алфавиты. Первой попыткой расширения ASCII был IS646, который расширял предыдущую кодировку еще на 128 символов. Добавлены были латинские буквы со штрихами и диакритическими знаками, и получил название — Latin 1. Следующая попытка была IS 8859 — которые содержал кодовую страницу. Были еще попытки расширений, но это все было не универсальным. Была создана кодировка UNICODE (is 10646). Идея кодировка в том, что бы приписать каждому символу единое постоянное 16-битное значение, которое называется — указателем кода. Всего получается 65536 указателей. Для экономии места использовали Latin-1 для кодов 0 -255, легко изменяя ASII в UNICODE. Такой стандарт решил много проблем, однако не все. В связи с поступлением новых слов, к примеру для японского языка нужно увеличивать количество терминов где-то на 20 тыс. Также нужно включить шрифт брайля.

Оценка статьи:

Загрузка…

Поделиться с друзьями:

Кодирование символов

Содержание урока

Общий подход

Кодировка ASCII и её расширения

Стандарт UNICODE

Вопросы и задания

Задачи

Стандарт UNICODE

Любая 8-битная кодовая страница имеет серьёзное ограничение — она может включать только 256 символов. Поэтому не получится набрать в одном документе часть текста на русском языке, а часть — на китайском. Кроме того, существует проблема чтения документов, набранных с использованием другой кодовой страницы. Всё это привело к принятию в 1991 г. нового стандарта кодирования символов — UNICODE, который позволяет записывать знаки любых существующих (и даже некоторых «мёртвых») языков, математические и музыкальные символы и др.

Если мы хотим расширить количество используемых знаков, необходимо увеличивать место, которое отводится под каждый символ. Вы знаете, что компьютер работает сразу с одним или несколькими байтами, прочитанными из памяти. Например, если увеличить место, отводимое на каждый символ, до двух байтов, то можно закодировать 216 = 65 536 символов в одном наборе. В современной версии UNICODE можно кодировать до 1 112 064 различных знаков, однако реально используются немногим более 100 000 символов.

В системе Windows используется кодировка UNICODE, называемая UTF-16 (от англ. UNICODE Transformation Format — формат преобразования UNICODE). В ней все наиболее важные символы кодируются с помощью 16 битов (2 байтов), а редко используемые — с помощью 4 байтов.

В Unix-подобных системах, например в Linux, чаще применяют кодировку UTF-8. В ней все символы, входящие в таблицу ASCII, кодируются в виде 1 байта, а другие символы могут занимать от 2 до 4 байтов. Если значительную часть текста составляют латинские буквы и цифры, такой подход позволяет значительно уменьшить объём файла по сравнению с UTF-16. Текст, состоящий только из символов таблицы ASCII, кодируется точно так же, как и в кодировке ASCII. По данным поисковой системы Google, на начало 2010 г. около 50% сайтов в Интернете использовали кодировку UTF-8.

Кодировки стандарта UNICODE позволяют использовать символы разных языков в одном документе. За это приходится «расплачиваться» увеличением объёма файлов.

Следующая страница Вопросы и задания

Cкачать материалы урока

Список символов Unicode категории «Другой символ»

U + 058D

֍

Армянский знак вечности, обращенный вправо

U + 058E

֎

Левый знак армянского вечности

U + 06DE

۞

Арабский Начало Руб Эль Хизб

U + 06FD

۽

Арабский знак Синдхи Амперсанд

U + 06FE

۾

Арабский знак Синдхи Постпозиционирование Мужчины

U + 0F01

Тибет

U + 0F01

Gter Yig Mgo Усеченный A

U + 0F02

Тибетский Mark Gter Yig Mgo undefined-Um Rnam Bcad Ma

U + 0F03

Tibetan Mark Gter Yig Mgoter 9-Ugm Mgo + 0F13

Тибетский знак Caret undefined-Dzud Rtags Me Long Can

U + 0F15

Знак тибетского логотипа Chad Rtags

U + 0F16

༖ 9000 Tibetan Log n Lhag Rtags

U + 0F17

Тибетский астрологический знак Sgra Gcan undefined-Char Rtags

U + 0F1A

Тибетский знак Rdel Dkar Gcig

U0002

U Дкар Гниис

U + 0F1C

Тибетский знак Рдел Дкар Гсум

U + 0F1D

Тибетский знак Рдел Наг Gcig

000

000

000 U + 0F1F

Тибетский знак Rdel Dkar Rdel Nag

U + 0F36

Тибетский Марк Карет undefined-Dzud Rtags Bzhi Mig Can

U + 0FBF2000 000 3

U + 0FC0

Тибетский кантилляционный знак Heavy Beat

U + 0FC1

Тибетский кантилляционный знак Light Beat

U + 0FC2

an

an

n Cang Te-U

U + 0FC3

Тибетский знак кантилляции Sbub undefined-Chal

U + 0FC7

Тибетский символ Rdo Rje Rgya Gram

U + 0 Nor Bu Nyis undefined-Khyil

U + 0FCB

Тибетский символ Nor Bu Gsum undefined-Khyil

U + 0FCC

Тибетский символ Nor Bu Bzhi undefinedCE 9000 9000 U0003

Тибетский знак Rdel Nag Rdel Dkar

U + 0FCF

Тибетский знак Rdel Nag Gsum

U + 0FD7

0FD7

9000

Знак Свасти с точками, обращенный влево

U + 109F

Символ Мьянмы Shan Exclamation

U + 1390

Эфиопский тональный знак Йизет

U + 1391

Эфиопский тональный знак Дерет

000 RON

000

000 Upic

000

000 U + 1393

Эфиопский тональный знак Шорт Рикрик

U + 1394

Эфиопский тональный знак Дифат

U + 1395

Эфиопский тональный знак

0003

U0003

Эфиопский тональный Марк Чирет

U + 1397

Эфиопский тональный Марк Хидет

U + 1398

Эфиопский тональный Марк Дерет-Хидет

U + 166D

U + 19E6

Кхмерский символ Прам-Муой Коэт

U + 19E7

Кхмерский символ Прам-Пии Коэт

U + 19E8

Кхмерский символ Pram-Bei Koet

U + 19E9

Кхмерский символ Pram-Buon Koet

U + 19EB

Кхмерский символ Dap-Muoy Koet

U + 19EC

Dap-Pii Koet

U + 19ED

Кхмерский символ Dap-Bei Koet

U + 19EE

Кхмерский символ Dap-Buon Koet

U + 19EF

Symbol

Детская коляска Koet

U + 19F6

Кхмерский символ Прам-Муой Roc

U + 19F7

Кхмерский символ Pram-Pii Roc

U + 19F8

Кхмерский символ Pram-Muoy Roc

U + 19F9

Кхмерский символ Прам-Буон Рок

U + 19FB

Кхмерский символ Dap-Muoy Roc

U + 19FE

Кхмерский символ Dap-Buon Roc

Кхмерский символ U + 19FF

᧿

Кхмерский символ Dap-Pram Roc 900 03

U + 1B61

Балийский музыкальный символ Донг

U + 1B62

Балийский музыкальный символ Дэн

U + 1B63

Балийский музыкальный символ

0002 U

Балийский музыкальный символ Данг

U + 1B65

Балийский музыкальный символ Данг Суранг

U + 1B66

Балийский музыкальный символ Динг

U + 1B67

U + 1B67

U + 1B68

Балийский музыкальный символ Деунг

U + 1B69

Балийский музыкальный символ Daing

U + 1B6A

Балийский музыкальный символ

000

000 9Dang Gede

Балийский музыкальный символ Открытая правая рука

U + 1B75

Балийский музыкальный символ Открытая правая рука

U + 1B76

Балийский музыкальный символ Закрытый тук для правой руки

U + 1B77

Балийский музыкальный символ Закрытый такт для правой руки

U + 1B78

Балийский музыкальный символ Левый открытый пан

U0003

1B79

Балийский музыкальный символ Открытый панг для левой руки

U + 1B7A

Балийский музыкальный символ Левый закрытый лист

U + 1B7B

Балийский музыкальный символ

U + 1B7C

Балийский музыкальный символ Левая рука Открытый пинг

U + 2117

Звукозапись Авторские права

U + 2129

Строчная греческая строчная буква

214F

Символ для Самаритянского источника

U + 219E

Стрелка с двумя головками влево

U + 21A1

Стрелка вниз с двумя головами 900 03

U + 21A2

Стрелка влево с хвостом

U + 21A9

Стрелка влево с крючком

U + 21AA

0003AB

000 U +

AB

0003

Стрелка влево с петлей

U + 21AC

Стрелка вправо с петлей

U + 21B0

Стрелка вверх с кончиком влево

U + 21B1

↱2000 2000

U + 21B2

Стрелка вниз с кончиком влево

U + 21B3

Стрелка вниз с кончиком вправо

U + 21B4

Стрелка вправо U +

Стрелка вправо

Стрелка вниз с углом влево

U + 21B6

Против часовой стрелки Верхняя полукруглая стрелка

U + 21B7

900 02 Стрелка в виде верхнего полукруга по часовой стрелке

U + 21B8

Стрелка с северо-запада на длинную полосу

U + 21B9

Стрелка влево до полосы сверху Стрелка вправо до полосы

U + 21BA

Стрелка с разомкнутым кругом против часовой стрелки

U + 21BB

Стрелка с разомкнутым кругом по часовой стрелке

U + 21BC

Гарпун влево с зазубриной вверх

U + 21BD

влево

влево

U + 21BE

Верхний гарпун с зазубриной вправо

U + 21BF

Верхний гарпун с зазубриной влево

U + 21C0

Вправо

Вверх ⇁

Гарпун направленный вправо с зазубриной вниз

U + 21C2

Гарпун направленный вниз с зазубриной вправо

U + 21C3

Гарпун вниз с зазубриной влево

U + 21C4

Стрелка вправо Стрелка вправо Наверх Стрелка влево

U + 21C5

Стрелка вверх Стрелка влево Стрелка влево

U + 21C2000

U + 21C2 Стрелка вправо

U + 21CB

Гарпун влево Гарпун вправо

U + 21CC

Гарпун вправо Двойной гарпун влево

U + 21CD

влево

U + 21DD

Изогнутая стрелка вправо

U + 21DE

Стрелка вверх с двойным ходом

U + 21DF

Стрелка вниз с двойным ходом 9 ⇪20003

U +

Белая стрелка вверх от бара

U + 21EB

Белая стрелка вверх на пьедестале

U + 21EC

9 0002 ⇬

Белая стрелка вверх на пьедестале с горизонтальной полосой

U + 21ED

Белая стрелка вверх на пьедестале с вертикальной чертой

U + 21EE

Белая двойная стрелка вверх

U

Белая двойная стрелка вверх на пьедестале

U + 21F0

Белая стрелка вправо от стены

U + 21F1

Северо-западная стрелка до угла

U + 21F2000

U + 21F2 Стрелка на юго-восток в угол

Как преобразовать ascii в unicode в C #

Вам по-прежнему нужен шрифт Rupee, см.:
http: // en.].

[РЕДАКТИРОВАТЬ]

В ответ на «но»:

вы должны понимать, что само понятие «преобразование» из Unicode в ASCII и ASCII в Unicode не имеет смысла, потому что Unicode… не кодирует, в отличие от ASCII. (Однако это зависит от того, что вы называете «Unicode», потому что на жаргоне Windows термин «Unicode» часто используется для обозначения одного из форматов преобразования Unicode (UTF), UTF16LE.) Unicode — это стандарт, который определяет формальный формат. однозначное соответствие между «персонажами», понимаемыми как некоторые культурные категории, абстрагированные из их точной графики (например, латинское «A» и кириллица «А» — это разные символы, вы можете проверить это с помощью текстового поиска в этом абзаце) и целыми числами , извлеченные из их компьютерного представления, такие как размер и порядок байтов.Несмотря на распространенное ошибочное мнение, это не 16-битный код, поскольку диапазон «кодовых точек», стандартизированный в настоящее время Unicode, выходит далеко за пределы диапазона, который может уместиться в 16-битном формате (называемый базовой многоязычной плоскостью, BMP). Поскольку существуют разные целочисленные типы, существует несколько разных способов представления текста в Юникоде, называемых UTF.

Windows внутренне представляет Unicode с использованием UTF16LE (и да, UTF16, а также UTF8 и UTF32 могут представлять кодовые точки за пределами первых 16 бит BMP), но все API хорошо абстрагируются от этого факта.UTF появляются, когда символьные данные сериализованы (не «преобразованы») в массив байтов. Символьные данные также могут быть сериализованы в ASCII, но некоторая информация может или не может быть потеряна, потому что диапазон ASCII составляет всего от 0 до 127, а точки символов имеют то же «значение», что и в Unicode. Традиционно потерянные символы (за пределами диапазона ASCII) «конвертируются» в ‘?’. Данные ASCII в виде массива байтов можно десериализовать в символьные данные (строку .NET) и, естественно, это всегда проходит без потерь.Другими словами, код ASCII имеет однозначное соответствие с подмножеством Unicode с кодовыми точками от 0 до 127.

Тем не менее, опять же: не существует такой концепции, как «преобразование» между ASCII и Unicode.

—SA

ASCII | коммуникации | Britannica

ASCII , аббревиатура Американского стандартного кода для обмена информацией , стандартный код передачи данных, который используется меньшими и менее мощными компьютерами для представления как текстовых данных (буквы, числа и знаки препинания), так и не вводимых -команды устройства (управляющие символы).Как и другие системы кодирования, он преобразует информацию в стандартизированные цифровые форматы, которые позволяют компьютерам обмениваться данными друг с другом и эффективно обрабатывать и хранить данные.

Код ASCII изначально был разработан для телетайпов, но со временем нашел широкое применение в персональных компьютерах. Стандартный код ASCII использует семизначные двоичные числа; , то есть чисел, состоящих из различных последовательностей нулей и единиц. Код может представлять 128 различных символов, поскольку существует 128 различных возможных комбинаций семи нулей и единиц.Двоичная последовательность 1010000, например, представляет собой заглавную букву «Р», а последовательность 1110000 представляет собой строчную букву «р».

Цифровые компьютеры используют двоичный код, который организован группами из восьми, а не из семи цифр или битов. Каждая такая группа из восьми цифр называется байтом. Поскольку цифровые компьютеры используют восьмибитные байты, код ASCII обычно встраивается в восьмибитовое поле, состоящее из семи информационных битов и бита четности, который используется для проверки ошибок или для представления специальных символов.Использование восьмибитной системы увеличило количество символов, которые может представлять код, до 256. Восьмибитная система, известная как расширенный код ASCII, была введена в 1981 году Международной корпорацией бизнес-машин (IBM) для использования. со своей первой моделью персонального компьютера. Этот расширенный код ASCII вскоре стал отраслевым стандартом для персональных компьютеров. В нем 32 кодовые комбинации используются для машинных и управляющих команд, таких как «начало текста», «возврат каретки» и «подача страницы».Следующая группа из 32 комбинаций используется для чисел и различных знаков пунктуации. Другая группа из 32 комбинаций используется для прописных букв и нескольких других знаков препинания, а последние 32 используются для строчных букв.

Другая система кодирования, EBCDIC (Extended Binary Coded Decimal Interchange Code), используется в мэйнфреймах и миникомпьютерах.

Получите эксклюзивный доступ к контенту нашего 1768 First Edition с подпиской.
Подпишитесь сегодня
.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *