Изменения
Пять бит могут кодировать 2^5 символов; это 32, а не 64
== Представление символов в вычислительных машинах ==
В вычислительных машинах символы не могут храниться иначе, как в виде последовательностей битов бит (как и числа). Для передачи символа и его корректного отображения ему должна соответствовать уникальная последовательность нулей и единиц. Для этого были разработаны таблицы кодировок.
Количество символов, которые можно задать последовательностью битов бит длины ''<tex>n''</tex>, задается простой формулой <tex>C(n) = 2^n</tex>. Таким образом, от нужного количества символов напрямую зависит количество используемой памяти.
== Таблицы кодировок ==
На заре компьютерной эры на каждый символ было отведено по 5 пять бит. Это было связано с малым количеством оперативной памяти на компьютерах тех лет. В эти 64 <tex>32</tex> символа входили только управляющие символы и строчные буквы английского алфавита.
С ростом производительности компьютеров стали появляться таблицы кодировок с большим количеством символов.
Первой 7 битной семибитной кодировкой стала ASCII7. В нее уже вошли прописные буквы английского алфавита, арабские цифры, знаки препинания.Затем на ее базе была разработана ASCII8, в которым уже стало возможным хранение <tex>256 </tex> символов: <tex>128 </tex> основных и еще столько же расширенных. Первая часть таблицы осталась без изменений, а вторая может иметь различные варианты (каждый имеет свой номер). Эта часть таблицы стала заполняться символами национальных алфавитов.
Но для многих языков (например, арабского, японского, китайского) <tex>256</tex> символов недостаточно, поэтому развитие кодировок продолжалось, что привело к появлению UNICODE.
==Кодировки стандарта ASCII==
{{Определение
|definition='''ASCII ''' {{- --}} таблицы кодировок, в которых содержатся основные символы (английский алфавит, цифры, знаки препинания, символы национальных алфавитов(свои для каждого региона), служебные символы) и длина кода каждого символа <tex>n = 8</tex> бит.
}}
== Наиболее известные кодировки =Способы представления===Юникод имеет несколько форм представления (англ. ''Unicode Transformation Format, UTF''): UTF-8, UTF-16 (UTF-16BE, UTF-16LE) и UTF-32 (UTF-32BE, UTF-32LE). Была разработана также форма представления UTF-7 для передачи по семибитным каналам, но из-за несовместимости с ASCII она не получила распространения и не включена в стандарт.
Символы UTF-8 получаются из Unicode cледующим образом:{|class="standardwikitable"
!Unicode||UTF-8||Представленные символы
|-
|||<code>111111xx</code>||служебные символы c, d, e, f
|}
Несмотря на то, что UTF-8 позволяет указать один и тот же символ несколькими способами, только наиболее короткий из них правильный. Остальные формы, называемые overlong sequence, отвергаются по соображениям безопасности.
====Принцип кодирования====
=====Правила записи кода одного символа в UTF-8=====
1. Если размер символа в кодировке UTF-8 = <tex>1</tex> байт<br />
: Код имеет вид (0aaa aaaa), где «0» — просто ноль, остальные биты «a» — это код символа в кодировке ASCII;
2. Если размер символа в кодировке в UTF-8 <tex>> 1</tex> байт (то есть от <tex>2</tex> до <tex>6</tex>):
: 2.1 Первый байт содержит количество байт символа, закодированное в '''единичной''' системе счисления;
2 — 11
3 — 111
4 — 1111
5 — 1111 1
6 — 1111 11
: 2.2 «0» — бит терминатор, означающий завершение кода размера
В общем случае варианты представления '''одного символа''' в кодировке UTF-8 выглядят так: (1 байт) 0aaa aaaa (2 байта) 110x xxxx 10xx xxxx (3 байта) 1110 xxxx 10xx xxxx 10xx xxxx (4 байта) 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx (5 байт) 1111 10xx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx (6 байт) 1111 110x 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx =====Определение длины кода в UTF-8====={| class="wikitable"|-! Количество байт UTF-8 !! Количество значащих бит|-| <center><tex>1</tex></center> || <center><tex>7</tex></center>|-| <center><tex>2</tex></center> || <center><tex>11</tex></center>|-| <center><tex>3</tex></center> || <center><tex>16</tex></center>|-| <center><tex>4</tex></center> || <center><tex>21</tex></center>|-| <center><tex>5</tex></center> || <center><tex>26</tex></center>|-| <center><tex>6</tex></center> || <center><tex>31</tex></center>|} В общем случае количество значащих бит <tex>C</tex>, кодируемых <tex>n</tex> байтами UTF-8, определяется по формуле: <tex>C =7</tex> при <tex>n=1</tex> <tex>C = n\cdot5+1</tex> при <tex>n>1</tex> ===UTF-16=BOM==UTF-16 {{---}} один из способов кодирования '''символов'''Byte Order Mark (BOMангл. ''code point'')из Unicode в виде последовательности <tex>16</tex>-битных '''слов''' (англ. ''code unit' '). Данная кодировка позволяет записывать символы Юникода в диапазонах U+0000..U+D7FF и U+E000..U+10FFFF (общим количеством <tex>1\ 112\ 064</tex>), причем <tex>4</tex>-байтные символы представляются как есть, а более длинные {{---}} с помощью суррогатных пар (англ. ''surrogate pair''), для которых и вырезан диапазон <tex>D800_{16}..DFFF_{16}</tex>. В UTF- 16 символы кодируются двухбайтовыми словами с использованием всех возможных диапазонов значений (от <tex>0000_{16}</tex> до <tex>FFFF_{16}</tex>). При этом можно кодировать символы Unicode символв дипазонах <tex>0000_{16}..D7FF_{16}</tex> и <tex>E000_{16}..10FFFF_{16}</tex>. Исключенный отсюда диапазон <tex>D800_{16}..DFFF_{16}</tex> используется как раз для кодирования так называемых суррогатных пар — символов, используемый которые кодируются двумя <tex>16</tex>-битными словами. Символы Unicode до <tex>FFFF_{16}</tex> включительно (исключая диапазон для индикации порядка байтов суррогатов) записываются как есть <tex>16</tex>-битным словом. Символы же в диапазоне <tex>10000_{16}..10FFFF_{16}</tex> (больше <tex>16</tex> бит) уже кодируются парой <tex>16</tex>-битных слов. Для этого их код арифметически сдвигается до нуля (из него вычитается минимальное число <tex>10000_{16}</tex>). В результате получится значение от нуля до <tex>FFFF_{16}</tex>, которое занимает до <tex>20</tex> бит. Старшие <tex>10</tex> бит этого значения идут в лидирующее (первое) слово, а младшие <tex>10</tex> бит — в последующее (второе). При этом в обоих словах старшие <tex>6</tex> бит используются для обозначения суррогата. Биты с <tex>11</tex> по <tex>15</tex> имеют значения <tex>11011_2</tex>, а <tex>10</tex>-й бит содержит <tex>0</tex> у лидирующего слова и <tex>1</tex> — у последующего. В связи с этим можно легко определить к чему относится каждое слово. ====UTF-16LE и UTF-16BE====Один символ кодировки UTF-16 представлен последовательностью двух байт или двух пар байт. Который из двух идёт впереди, старший или младший, зависит от порядка байт. Подробнее об этом будет сказано ниже. ===UTF-32===UTF-32 {{---}} один из способов кодирования символов из Юникод, использующий для кодирования любого символа ровно <tex>32</tex> бита. Остальные кодировки, UTF-8 и UTF-16, используют для представления символов переменное число байт. Символ UTF-32 является прямым представлением его кодовой позиции (англ. ''code point''). Главное преимущество UTF-32 перед кодировками переменной длины заключается в том, что символы Юникод непосредственно индексируемы. Получение <tex>n</tex>-ой кодовой позиции является операцией, занимающей одинаковое время. Напротив, коды с переменной длиной требует последовательного доступа к <tex>n</tex>-ой кодовой позиции. Это делает замену символов в строках UTF-32 простой, для этого используется целое число в качестве индекса, как обычно делается для строк ASCII. Главный недостаток UTF-32 {{---}} это неэффективное использование пространства, так как для хранения символа используется четыре байта. Символы, лежащие за пределами нулевой (базовой) текстового файлаплоскости кодового пространства редко используются в большинстве текстов. Поэтому удвоение, в сравнении с UTF-16, занимаемого строками в UTF-32 пространства не оправдано. Хотя использование неменяющегося числа байт на символ удобно, но не настолько, как кажется. Операция усечения строк реализуется легче в сравнении с UTF-8 и UTF-16. Но это не делает более быстрым нахождение конкретного смещения в строке, так как смещение может вычисляться и для кодировок фиксированного размера. Его кодовый Это не облегчает вычисление отображаемой ширины строки, за исключением ограниченного числа случаев, так как даже символ U+FEFF «фиксированной ширины» может быть получен комбинированием обычного символа с модифицирующим, который не имеет ширины. Например, буква «й» может быть получена из буквы «и» и диакритического знака «крючок над буквой». Сочетание таких знаков означает, что текстовые редакторы не могут рассматривать <tex>32</tex>-битный код как единицу редактирования. Редакторы, которые ограничиваются работой с языками с письмом слева направо и составными символами (англ. ''Precomposed character''), могут использовать символы фиксированного размера. Но такие редакторы вряд ли поддержат символы, лежащие за пределами нулевой (ZERO WIDTH NONбазовой) плоскости кодового пространства и вряд ли смогут работать одинаково хорошо с символами UTF-BREAKING SPACE16. ===Порядок байт===В современной вычислительной технике и цифровых системах связи информация обычно представлена в виде последовательности байт. В том случае, если число не может быть представлено одним байтом, имеет значение в каком порядке байты записываются в памяти компьютера или передаются по линиям связи. Часто выбор порядка записи байт произволен и определяется только соглашениями. В общем случае, для представления числа <tex>M</tex>, большего <tex>255</tex> (здесь <tex>255=2^8-1</tex> — максимальное целое число, записываемое одним байтом), приходится использовать несколько байт. При этом число <tex>M</tex> записывается в позиционной системе счисления по основанию <tex>256</tex>: <tex>M = \sum_{i=0}^{n}A_i\cdot 256^i=A_0\cdot 256^0+A_1\cdot 256^1+A_2\cdot 256^2+\dots+A_n\cdot 256^n.</tex> Набор целых чисел <tex>A_0,\dots,A_n</tex>, каждое из которых лежит в интервале от <tex>0</tex> до <tex>255</tex>, является последовательностью байт, составляющих <tex>M</tex>. При этом <tex>A_0</tex> называется младшим байтом, а <tex>A_n</tex> — старшим байтом числа <tex>M</tex>. ====Варианты записи=========Порядок от старшего к младшему=====Порядок от старшего к младшему (англ. ''неразрывный пробел с нулевой ширинойbig-endian''): <tex>A_n, также именуемый \dots,A_0</tex>, запись начинается со старшего и заканчивается младшим. Этот порядок является стандартным для протоколов TCP/IP, он используется в заголовках пакетов данных и во многих протоколах более высокого уровня, разработанных для использования поверх TCP/IP. Поэтому, порядок байт от старшего к младшему часто называют сетевым порядком байт (англ. ''меткой порядка байтовnetwork byte order'' ). Этот порядок байт используется процессорами IBM 360/370/390, Motorola 68000, SPARC (англ. отсюда третье название — порядок байт Motorola, Motorola byte order mark). В этом же виде (используя представление в десятичной системе счисления) записываются числа индийско-арабскими цифрами в письменностях с порядком знаков слева направо (латиница, BOMкириллица). По спецификации Для письменностей с обратным порядком (арабская) та же запись числа воспринимается как «от младшего к старшему». Порядок байт от старшего к младшему применяется во многих форматах файлов — например, PNG, FLV, EBML. =====Порядок от младшего к старшему=====Порядок от младшего к старшему (англ. ''little-endian''): <tex>A_0,\dots,A_n</tex>, запись начинается с младшего и заканчивается старшим. Этот порядок записи принят в памяти персональных компьютеров с x86-процессорами, в связи с чем иногда его использование называют интеловский порядок байт (по названию фирмы-создателя архитектуры x86). В противоположность порядку big-endian, соглашение little-endian поддерживают меньше кросс-платформенных протоколов и форматов данных; существенные исключения: USB, конфигурация PCI, таблица разделов GUID, рекомендации FidoNet. =====Переключаемый порядок=====Многие процессоры могут работать и в порядке от младшего к старшему, и в обратном, например, ARM, PowerPC (но не является обязательнымPowerPC 970), DEC Alpha, MIPS, PA-RISC и IA-64. Обычно порядок байт выбирается программно во время инициализации операционной системы, однако если BOM но может быть выбран и аппаратно перемычками на материнской плате. В этом случае правильнее говорить о порядке байт операционной системы. Переключаемый порядок байт иногда называют англ. ''bi-endian''. =====Смешанный порядок=====Смешанный порядок байт (англ. ''middle-endian'') иногда используетсяпри работе с числами, то он должен быть установлен вначале текстового файладлина которых превышает машинное слово. Помимо своего конкретного использования Число представляется последовательностью машинных слов, которые записываются в формате, естественном для данной архитектуры, но сами слова следуют в качестве указателя порядка байтовобратном порядке. Классический пример middle-endian — представление <tex>4</tex>-байтных целых чисел на <tex>16</tex>-битных процессорах семейства PDP-11 (известен как PDP-endian). Для представления двухбайтных значений (слов) использовался порядок little-endian, символ может также указать какой кодировкой Unicode закодирован текстно <tex>4</tex>-хбайтное двойное слово записывалось от старшего слова к младшему. В процессорах VAX и ARM используется смешанное представление для длинных вещественных чисел. =====Различия=====[[Файл:Bomendian.png|thumb|right| 400px300px]]Когда символ закодирован Существенным достоинством little-endian по сравнению с big-endian порядком записи считается возможность «неявной типизации» целых чисел при чтении меньшего объёма байт (при условии, что читаемое число помещается в диапазон). Так, если в UTF-ячейке памяти содержится число <tex>00000022_{16}</tex>, то прочитав его 2 или 4 как int16 (два байта можно упорядочить двумя разными способами () мы получим число <tex>0022_{16}</tex>, прочитав один байт — число <tex>22_{16}</tex>. Однако, это же может считаться и недостатком, потому что провоцирует ошибки потери данных. Обратно, считается что у little-endian или , по сравнению с big-endianесть «неочевидность» значения байт памяти при отладке (последовательность байт (A1, B2, C3, D4). Изображение ниже показывает это. byteна самом деле значит <tex>D4C3B2A1_{16}</tex>, для big-order mark указываетendian эта последовательность (A1, B2, какой порядок используетсяC3, так что приложения могут немедленно расшифровать контентD4) читалась бы «естественным» для арабской записи чисел образом: <tex>A1B2C3D4_{16}</tex>). UTFНаименее удобным в работе считается middle-16 контент должен всегда начинатся с BOMendian формат записи; он сохранился только на старых платформах.
== Представление BOM в кодировках ==Маркер последовательности байт====Для определения формата представления Юникода в начало текстового файла записывается сигнатура — символ U+FEFF (неразрывный пробел с нулевой шириной), также именуемый маркером последовательности байт (англ. ''byte order mark (BOM)''). Это позволяет различать UTF-16LE и UTF-16BE, поскольку символа U+FFFE не существует.[[Файл:Bom.png|thumb|right| 400px]]
{| class="wikitable"
|+'''Представление BOM в кодировках'''
|-
! Кодирование
|-
|}
В кодировке UTF-8, наличие BOM не является существенным, поскольку, нет альтернативной последовательности байт. Когда BOM используется на страницах или редакторах для контента закодированного в UTF-8, иногда он может представить пробелы или короткие последовательности символов, имеющие странный вид (такие как ). Именно поэтому, при наличии выбора, для совместимости, как правило, лучше упустить BOM в UTF-8 контенте.Однако BOM могут еще встречаться в тексте закодированном в UTF-8, как побочный продукт перекодирования или потому, что он был добавлен редактором. В этом случае BOM часто называют подписью UTF-8.
Когда символ закодирован в UTF-16, его <tex>2</tex> или <tex>4</tex> байта можно упорядочить двумя разными способами (little-endian или big-endian). Изображение справа показывает это. Byte order mark указывает, какой порядок используется, так что приложения могут немедленно расшифровать контент. UTF-16 контент должен всегда начинатся с BOM.
BOM также используется для текста обозначенного как UTF-32. Аналогично UTF-16 существует два варианта четырёхбайтной кодировки — UTF-32BE и UTF-32LE. К сожалению, этот способ не позволяет надёжно различать UTF-16LE и UTF-32LE, поскольку символ U+0000 допускается Юникодом
===Проблемы Юникода===
В Юникоде английское «a» и польское «a» {{---}} один и тот же символ. Точно так же одним символом (но отличающимся от «a» латинского) считаются русское «а» и сербское «а». Такой принцип кодирования не универсален; по-видимому, решения «на все случаи жизни» вообще не может существовать.
==Примеры==
Если записать строку 'hello мир' в файл exampleBOM, а затем сделать его hex-дамп, то можно убедиться в том, что разные символы кодируются разным количеством байт. Например, английские буквы,пробел, знаки препинания и пр. кодируются одним байтом, а русские буквы - двумя
===Код на python===
<pre>
#!/usr/bin/env python
#coding:utf-8
import codecs
f = open('exampleBOM','w')
b = u'hello мир'
f.write(codecs.BOM_UTF8)
f.write(b.encode('utf-8'))
f.close()
</pre>
===hex-дамп файла exampleBOM===
{|class = "wikitable" border = "1" style="text-align:center"
|Символ
|colspan="3" |BOM
|h||e||l||l||o
|Пробел
|colspan="2" |м
|colspan="2" |и
|colspan="2" |р
|-
|Код в UNICODE
|EF
|BB
|BF
|68||65||6C||6C||6F
|20||D0||BC||D0||B8||D1||80
|-
|Код в UTF-8
|11101111||10111011||10111111
|01101000||01100101||01101100||01101100||01101111
|00100000||11010000||10111100||11010000||10111000||11010001||10000000
|}
==См. также==
* [[Представление целых чисел: прямой код, код со сдвигом, дополнительный код]]
* [[Представление вещественных чисел]]
== Источники информации ==
* [http://ru.wikipedia.org/wiki/ASCII Wikipedia {{---}} таблица ASCII]
* [http://ru.wikipedia.org/wiki/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4 Wikipedia {{---}} стандарт UNICODE]
* [http://ru.wikipedia.org/wiki/Byte_order_mark Wikipedia {{---}} Byte order mark]
* [http://ru.wikipedia.org/wiki/Порядок_байтов Wikipedia {{---}} Порядок байтов]
* [http://ru.wikipedia.org/wiki/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4 Wikipedia {{---}} Юникод]
* [http://ru.wikipedia.org/wiki/CP1251 Wikipedia {{---}} Windows-1251]
* [http://ru.wikipedia.org/wiki/UTF-8 Wikipedia {{---}} UTF-8]
* [http://ru.wikipedia.org/wiki/UTF-16 Wikipedia {{---}} UTF-16]
* [http://ru.wikipedia.org/wiki/UTF-32 Wikipedia {{---}} UTF-32]
[[Категория: Дискретная математика и алгоритмы]]
[[Категория: Представление информации]]