Skip to content

Latest commit

 

History

History
315 lines (240 loc) · 19.9 KB

Encoding.md

File metadata and controls

315 lines (240 loc) · 19.9 KB

Системы счисления

Система счисления (англ. numeral system, system of numeration) — представление чисел при помощи символов.

Двоичная, бинарная (англ. binary): 0, 1.
Десятичная (англ. decimal): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Шестнадцатеричная (англ. hexadecimal): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.

Чтобы не путать с 10 с/с, к числу в 16 с/с обычно добавляют 0x в начало или h (₁₆) в конец.
Чтобы не путать с 10 с/с, к числу в 2 с/с обычно добавляют b () в конец.
10 с/с считается стандартной, поэтому к числу обычно ничего не добавляют (но иногда можно явно указать ₁₀).

Двоичные цифры 0 и 1 называют битами (англ. bit), они взаимоисключаемы: 0 - ложь, 1 - истина.

Байт (англ. byte), октет (англ. octet) — последовательность из 8 бит, её можно компактно представить в виде шестнадцатеричного числа.

00000000₂ = 0x0
10110011₂ = 0xB3
11111111₂ = 0xFF

Аналогично, ниббл (англ. nibble), полубайт (англ. half-byte) или тетрада (англ. tetrade) — 4 бита, слово (англ. word) — 16 бит, двойное слово (англ. double word, dword) — 32 бита.

Отсчёт битов в двоичном числе начинается с нуля и идёт справа налево.
Младший бит (англ. least significant, low-order) — крайний справа, старший бит (англ. most significant, hight-order) — крайний слева.

Порядок байтов от старшего к младшему (англ. big-endian, BE) соответствует порядку записи арабских цифр: 123 (сто двадцать три). Этот порядок также называют сетевым порядком байтов, поскольку он является стандартным для протоколов TCP/IP. Используется также в технической и учебной литературе, в PNG и JPEG.

Порядок байтов от младшего к старшему (англ. little-endian, LE) соответствует обратному порядку записи арабских цифр: 321 (сто двадцать три). Этот порядок также называют интеловским порядком байтов, так как он используется в памяти ПК с процессорами архитектуры x86.

Представление чисел в различных с/с

Числовой разряд — место, позиция цифры в числе.

Разряды начинают считать справа налево (BE), начиная с нулевого.

Представление чисел в N c/c: число представляется в виде многочлена степени n - 1 (n - количество цифр),
с переменной N и цифрами в качестве коэффициентов.

/* в 10 с/с */
/* 4 - нулевой разряд, 3 - первый, 2 - второй, 1 - третий */
1234₁₀ = 1 * 10³ + 2 * 10² + 3 * 10¹ + 4 * 10⁰

/* в 16 с/с */
/* C₁₆ - нулевой разряд, B₁₆ - первый, A₁₆ - второй */
ABC₁₆ = A₁₆ * (10₁₆)² + B₁₆ * (10₁₆)¹ + C₁₆ * (10₁₆)⁰

/* в 2 с/с */
/* 0₂ - нулевой разряд, 1₂ - первый, 1₂ - второй */
110₂ = 1₂ * (10₂)² + 1₂ * (10₂)¹ + 0₂ * (10₂)⁰

Перевод чисел в 10 с/с из другой c/c.

/* из 16 c/c */
/* A₁₆ = 10, B₁₆ = 11, C₁₆ = 12 */
ABC₁₆ = 10 * 16² + 11 * 16¹ + 12 * 16⁰ = 2748

/* из 2 с/c */
/* 1₂ = 1, 0₂ = 0 */
110₂ = 1 *+ 1 *+ 0 * 2⁰ = 6

Перевод чисел из 10 с/с в другую N с/c:
последовательно делим число в 10 с/с на N до тех пор, пока не останется остаток <= (N - 1), ответ состоит из остатков деления в обратном порядке.

/* в 2 с/с */
22₁₀
22 / 2 = 11 (ост. 0)
11 / 2 = 5 (ост. 1)
5 / 2 = 2 (ост. 1)
2 / 2 = 1 (ост. 0)
1 <= 1 (ост. 1)
10110₂

/* в 16 с/с */
7327₁₀
7327 / 16 = 457 (ост. 15)
457 / 16 = 28 (ост. 9)
28 / 16 = 1 (ост. 12)
1 <= 15 (ост. 1)
/* 12₁₀ → C₁₆, 15₁₀ → F₁₆ */
1C9F₁₆

Другие переводы (например, 2 c/c -> 16 c/c) можно проводить в два действия: 2 с/c -> 10 c/c -> 16 c/c.

Кодировки символов

Символ (англ . character) — минимальная единица текста, имеющая семантическое значение.

Пример символов: G — латинская буква G, ( — открывающая круглая скобка, < — знак меньше.

Множество символов (англ. character set) — набор, совокупность символов, которые могут быть использованы в разных языках.

Например, множество символов { A, B, C, D } используются в английском, немецком и других языках.

Кодировка символов (англ. character encoding, charset) — представление символов какой-то системой кодирования.

Закодированное множество символов (англ. coded character set) — множество символов, каждый символ которого соответствует какому-то уникальному номеру.

/* закодированное множество символов { A, B, C, D } (ключ — значение) */

/* ASCII */
65 — A
66 — B
67 — C
68 — D

/* Unicode */
U+41 — A
U+42 — B
U+43 — C
U+44 — D

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

Взаимно однозначное соответствие, биекция (англ. bijection) — такое соответствие между элементами двух множеств, при котором каждому элементу первого множества соответствует один определенный элемент второго множества, а каждому элементу второго множества — один определенный элемент первого множества. image

Кодовая точка, позиция кода (англ. code point, code position) — любой элемент из множества уникальных номеров заданной кодировки.

В примере выше кодовыми точками в кодировках ASCII и Unicode являются 66, 66, 67, 68 и U+41, U+42, U+43, U+44 соответственно.

Количество кодовых точек в различных кодировках:

  • ASCII - 128 кодовых точек (0 - 7F).
  • Extended ASCII - 256 (0 - FF).
  • Unicode - 1114112 (0 - 10FFFF), поскольку состоит из 17 плоскостей (каждая из них содержит 2¹⁶ кодовых точек).

К кодовым точкам Unicode принято добавлять U+ в начало, чтобы можно было отличить кодировку от других.

/* кодовые точки латинской буквы "M" */
UTF-8:  U+4D
UTF-16: U+004D
UTF-32: U+0000004D

/* кодовые точки фигурной скобки "{" */
UTF-8:  U+65115
UTF-16: U+65115
UTF-32: U+00065115

Кодовая единица (англ. code unit) — последовательность бит, используемая для кодирования символа из множества символов заданной кодировки.

Кодовая единица состоит из заданного кодировкой количества бит:

  • ASCII - 7 бит
  • UTF-8 - 8 бит
  • UTF-16 - 16 бит
  • UTF-32 - 32 бит

Каждая кодовая точка представляется в виде последовательности кодовых единиц.

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

  • UTF-8: 1-4 кодовых единиц
  • UTF-16: 1-2 кодовые единицы (две требуеются для символов, идущих после U+10000)
  • UTF-32: 1 кодовая единица
/* кодовые единицы латинской буквы "M" */
UTF-8:  4D
UTF-16: 004D
UTF-32: 0000004D

/* кодовые единицы фигурной скобки "{" */
UTF-8:  EF B9 9B
UTF-16: FE5B
UTF-32: 0000FE5B

ASCII

ASCII (American Standard Code for Information Interchange) — американский стандартный код для обмена информацией.

Большинство кодировок символов берут ASCII за основу (например, Unicode), дополняя её другими символами.

ASCII создавалась для кодирования символов, коды которых вмещались в 7 бит (2⁷ = 128 символов), 8-ой бит использовался для ошибок, возникших при передаче данных.

На большинстве компьютеров минимально адресуемая единица памяти — байт (8 бит), поэтому там используются 8-битные вместо 7 (добавляется дополнительный старший бит, например, 0).

Затем появилась расширенная ASCII кодировка (англ. extended ASCII), использующая 8 бит (2⁸ = 256 символов).

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

  • EOT (англ. end of transmission) — конец файла
  • LF (line feed) — перевод строки (характерен для Unix)
  • CR (carriage return) — возврат каретки (курсор перемещается в начало текущей строки, не переходя на новую)
  • CR LF - перевод строки (характерен для Windows)
  • FF (form feed) — прогон страницы (продолжить печать со следующего листа)
  • BS (backspace) — возврат на один символ
  • DEL (delete) — стереть последний символ
  • TAB (tab) — горизонтальная табуляция
  • CAN (cancel) — отмена
  • и другие.

С помощью символа BS (возврат на один символ) можно печатать один символ поверх другого (например, добавить диакритический знак).

  • a BS ' → á
  • c BS , → ç
  • o BS / → ø
  • t BS tt (дважды тот же символ — выделение жирным)

Существуют национальные варианты ASCII, где некоторые символы заменяются на свойственные языку.

Кодирование и декодирование

UTF

UTF (Unicode Transformation Format) — формат преобразования Юникода.

Маркер последовательности байтов, метка порядка байтов (Byte Order Mark, BOM) — специальный Unicode-символ U+FEFF, вставляемый в начало текстового файла или потока, чтобы указать кодировку и порядок байтов, с помощью которых символы Unicode были закодированы. Маркер не обязателен, но очень желателен.

U+FEFF /* кодовое слово маркера */

/* кодовые единицы */
EF BB BF     /* UTF-8 */
FE FF        /* UTF-16 (BE) */
FF FE        /* UTF-16 (LE) */
00 00 FE FF  /* UTF-32 (BE) */
FF FE 00 00  /* UTF-32 (LE) */

Алгоритм кодирования UTF-8

  1. Определить кодовую точку (номер) рассматриваемого символа в Unicode.
$       /* символ */
U+0024  /* кодовая точка */
  1. Определить по кодовой точке количество октетов (байтов, последовательностей из 8 бит; 1 - 4), требуемых для кодирования символам.
0 - 7F          /* 1 октет */
80 - 7FF        /* 2 октета */
800 - FFFF      /* 3 октета */
10000 - 10FFFF  /* 4 октета */
  1. Установить старшие биты первого октета, опираясь на вычисленное количество необходимых октетов (0 - 1 октет, 110 - 2 октета, 1110 - три октета, 11110 - четыре октета), во 2-4 октетах установить старшие биты равными 10. При декодировании файла это позволяет определить, где начинается новая точка и сколько следующих октетов она занимает.
0xxxxxxx                             /* 1 октет */
110xxxxx 10xxxxxx                    /* 2 октета */
1110xxxx 10xxxxxx 10xxxxxx           /* 3 октета */
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  /* 4 октета */
  1. x - значащие биты. Вместо них нужно подставить биты кодовой точки в двоичном представлении. Если их не хватает, чтобы заполнить все значащие биты, заполняем старшие значащие биты нулями. В результате получим последовательность кодовых единиц.
€ → 0xE2 0x82 0xAC

Полные примеры кодирования символов:

$                      /* символ */
U+0024                 /* кодовая точка */
24₁₆ < 7F₁₆            /* 1 октет */
0xxxxxxx               /* маска */
24₁₆ = 36₁₀ = 100100₂  /* двоичное представление кодовой точки */
00100100               /* кодовые единицы в 2 с/с */
0x24                   /* кодовые единицы в 16 с/с *//* символ */
U+20AC                             /* кодовая точка */
800 < 20AC < FFFF                  /* 3 октета */
1110xxxx 10xxxxxx 10xxxxxx         /* маска */
20AC₁₆ = 8364₁₀ = 10000010101100₂  /* двоичное представление кодовой точки */
11100010 10000010 10101100         /* кодовые единицы в 2 с/с */ 
0xE2 0x82 0xAC                     /* кодовые единицы в 16 с/с */

Алгоритм декодирования UTF-8

Аналогично, но наоборот

Имеем поток байт.

Медиа тип (MIME type)

Медиа тип, MIME тип (англ. Media type, MIME type, Multipurpose Internet Mail Extensions) это стандарт, описывающий природу и формат файла или набора байтов.

Медиа типы определёны и стандартизированы в спецификации RFC 6838.

Ответственной организацией за все официальные медиа типы, то есть официально стандартизированные, является IANA (The Internet Assigned Numbers Authority). Страница про медиа типы на их сайте: https://www.iana.org/assignments/media-types/media-types.xhtml.

Структура MIME типа

MIME тип состоит из типа (англ. type) и подтипа (англ. subtype). Они разделяются наклонной чертой /.

type/subtype

Типом (англ. type) называют общую категория данных (например, text, aplication, video, audio, image).

Подтипом (англ. subtype) называют подкатегорию. (например, простой текст text/plain, HTML text/html).

Параметры MIME типа

К MIME типу опционально может быть добавлен параметр после ;.

type/subtype;param=value

Например, для текста в качестве параметра может быть указана кодировка. Для задания кодировки (англ. charset) UTF-8 используется text/plain;charset=UTF-8. Если параметр charset не задан, его значение по умолчанию US-ASCII (text/plain;charset=ASCII). Другие кодировки можно найти здесь.

Регистр MIME типа

Регистр не имеет значения (англ. case insensitive) для всего, кроме значения параметра value. Как правило, используют нижний регистр, значение параметра может быть в любом регистре.