Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Юникод. Погружение




Юникод

Введение в Юникод.

Юникод спроектирован для представления системой каждого символа любого языка. Юникод представляет каждую букву, символ или идеографию как 4-х байтное число. Каждое число представляет уникальный символ, используемый по крайней мере в одном из языков в мире. (используются больше чем 65535 из них, таким образом 2 байта не были бы достаточны. ) У символов, которые используются в разных языках, один код, если нет хорошей этимологической причины. Независимо от всего, есть точно 1 код сответствующий символу, и точно 1 символ соответствующий числовому коду. Каждый код всегда означает только один символ; нет никаких «режимов». U+0041 всегда соответствует 'A', даже если в вашем языке нету символа 'A'.

На первый взгляд, это великолепная идея. Одна кодировка для всего. Множество языков в одном документе. Не надо больше никаких «переключений режимов» для смены кодировок. Но у вас должен возникнуть очевидный вопрос. Четыре байта? На каждый символ? Это кажется ужасно расточительным, особенно для таких языков, как английский или испанский, в которых нужно меньше одного байта (256 чисел) для представления любого возможного символа. На самом деле, это расточительно даже для иероглифических языков (таких как китайский), в которых никогда не нужно больше, чем два байта на символ.

Существует кодировка Юникод, которая использует четыре байта на символ. Она называется UTF-32, так как 32 бита = 4 байтам. UTF-32 — прямолинейная кодировка; каждому символу Юникод (4-байтовому числу) соответствует символ с определенным номером. Это имеет свои преимущества, самое важное из которых заключается в том, что вы можете найти N-ый символ в строке за постоянное время, так как N-ый символ начинается в 4*N байте. Но эта кодировка также имеет и недостатки, самый очевидный из которых — для хранения каждого символа требуется четыре байта.

Хотя в Юникоде существует огромное количество символов, на самом деле большинство людей никогда не используют те, номера которых выше 65535 (2^16). Поэтому существует другая кодировка Юникода, называемая UTF-16 (очевидно что 16 бит = 2 байтам). UTF-16 кодирует каждый символ в номерах 0–65535; для представления же редко используемых " запредельных" символов с номерами выше 65535 приходится прибегать к некоторым уловкам. Самое очевидное преимущество: UTF-16 дважды эффективнее по потреблению памяти, нежели UTF-32, так как каждый символ требует 2 байта вместо 4-х (кроме случаев с теми самыми " запредельными" символами). И, как и в случае с UTF-32, можно легко отыскать нужный N-ый символ в строке за постоянное время, если вы уверены, что текст не содержит " запредельных" символов; и всё хорошо, если это действительно так.

Тем не менее существуют неочевидные недостатки, как UTF-32, так и UTF-16. На различных компьютерных платформах отдельные байты хранятся по-разному. Это означает, что символ U+4E2D может быть сохранён в UTF-16 либо как 4E 2D, либо как 2D 4E (задом наперёд), в зависимости от используемого порядка байт: big-endian или little-engian. (Для UTF-32 видов порядков даже больше. ) Пока вы храните свои документы исключительно у себя на компьютере, вы в безопасности — различные приложения на одном компьютере всегда используют один и тот же порядок. Но в тот момент, когда вы захотите передать документы на другой компьютер в Интернете или иной сети, вам понадобится способ пометки документа, какой у вас используется порядок байт. В противном случае, принимающая документ система не имеет понятия, что представляет последовательность байт " 4E 2D": U+4E2D или U+2D4E.

Для решения этой проблемы многобайтовые кодировки Юникода имеют “отметку о порядке байт” (BOM), которая представляет собой специальный непечатный символ, который вы можете включить в начало документа для сохранения информации о используемом порядке байт. Для UTF-16, эта отметка имеет номер U+FEFF. Если вы принимаете документ с UTF-16, который начинается с байт FF FE, — это однозначно оповещает о прямом порядке; если же начинается с байт FE FF, следовательно порядок обратный.

На самом деле, UTF-16 не идеален, особенно если вы имеете дело с большим количеством символов ASCII. Вы не думали о том, что даже китайская веб-страница может содержать большое количество символов ASCII — все элементы и атрибуты, окружающие печатные китайские символы (и на них тоже тратится 2 байта, хотя они и умещаются в один). Возможность искать N-ый символ в строке за постоянное время заманчива, однако до сих пор существует надоевшая всем проблема с теми " запредельными" символами, которая заключается в том, что вы не можете гарантировать, что каждый символ хранится точно в двух байтах, вследствие чего поиск за постоянное время также становится невозможным (если вы только не имеете отдельный индекс по символам). Открою вам секрет: и до сих пор в мире существует огромное число ASCII текстов...

Кое-кто до вас тоже задумывался над этой проблемой и пришёл вот к такому решению:

UTF-8

UTF-8 это кодировка Юникода с переменным числом байт. Это означает, что различные символы занимают разное число байт. Для символов ASCII (A-Z, цифр и т. п. ) UTF-8 использует только 1 байт на символ (действительно, а больше и не требуется). Причём и на деле для них зарезервированы точно те самые номера, как и в ASCII; первые 128 символов (0–127) таблицы UTF-8 неотличимы от той же части ASCII. “Расширенные” символы, такие как ñ и ö занимают два байта. (bytes are not simply the Unicode code point like they would be in UTF-16; there is some serious bit-twiddling involved. ) Китайские символы, такие как 中 занимают три байта. Самые редко используемые символы — четыре.

Недостатки: так как каждый символ занимает различное число байт, поиск N-го символа обладает сложностью O(N), что означает, что время поиска пропорционально длине строки. Кроме того, bit-twiddling, применяемый для кодирования символов в байты, также увеличивает время поиска. (прим. перев. в кодировке с фиксированным числом байт на символ время поиска составляет O(1), то есть оно не зависит от длины строки).

Преимущества: крайне эффективное кодирование наиболее часто используемых символов ASCII. Не хуже, чем хранение расширенных символов в UTF-16. Лучше, чем UTF-32 для китайских символов. Также (не хочу грузить вас математикой, так что вам придётся поверить мне на слово), в связи с самой природой bit twiddling, проблемы с порядком байт просто не существует. Документ, закодированный в UTF-8, использует один и тот же порядок байт на любом компьютере!

Погружение

В языке программирования Python 3 все строки представляют собой последовательность Unicode символов. В Python нет такого понятия, как строка в кодировке UTF-8, или строка в кодировке CP-1251. Некорректным является вопрос: " Это строка в UTF-8? " UTF-8 — это способ закодировать символы в последовательность байт. Если Вы хотите взять строку и превратить её в последовательность байт в какой-либо кодировке, то Python 3 может помочь Вам в этом. Если же Вы желаете превратить последовательность байт в строку, то и здесь Python 3 Вам пригодится. Байты — это не символы, байты — это байты. Символы — это абстракция. А строка — это последовательность таких абстракций.

> > > s = '深 入 Python' ①
> > > len(s) ②
9
> > > s[0] ③
'深 '
> > > s + ' 3' ④
'深 入 Python 3'

  • ① Чтобы создать строку окружите её кавычками. В Python строки можно создавать как с помощью одинарных ('), так и с помощью двойных кавычек (" ).
  • ② Стандартная функция len() возвращает длину строки, т. е. количество символов в ней. Эта же функция используется для определения длины списков, кортежей, множеств и словарей. Строка в данном случае похожа на кортеж символов.
  • ③ Так же как и со списками, Вы можете получить произвольный символ из строки, зная его индекс.
  • ④ Так же как и со списками, Вы можете объединять строки, используя оператор +.
Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...