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

На высоком уровне мы знаем, что все данные, передаваемые через Интернет в пакетах, состоящих из байтов, поэтому, когда дело доходит до кодировки символов, возникает вопрос: как все символы, которые наши пользователи вводят в формы, или которые мы извлекаем, или отправлять в базу данных или получать от внешних вызовов API, становиться байтами, которые можно передавать по сети?

Нам нужен способ превратить все эти числа, буквы и символы в биты - это называется кодированием.

Наборы символов

Набор символов технически не является кодировкой, но является необходимым условием для этого. Он представляет набор символов, которые могут быть закодированы, и обычно присваивает им значение, которое преобразуется в байты на этапе кодирования. Примеры ASCII и Unicode.

ASCII

ASCII был одним из первых наборов символов. Вот таблица, в которой показано, как включаются символы:

Проблема здесь сразу же очевидна, не так ли? Что, если вы хотите использовать нелатинский алфавит? Что делать, если вы хотите использовать специальный символ (например: ©)? Вы не можете. Таким образом, хотя ASCII все еще используется (например, все URL-адреса должны использовать только символы ASCII), на самом деле он не очень полезен для передачи данных по сети.

Юникод

Введите юникод. Юникод был разработан как глобальный стандарт для кодирования всех символов на всех языках (не говоря уже о смайликах и других специальных символах). На самом деле Unicode использует те же сопоставления символов, что и ASCII, для символов, которые в него включены, просто он включает намного больше (много - существует 1,114 112 возможных символов Unicode. Вы можете увидеть их все сюда , если интересно!).

Кодирование

Кодирование - это то, как мы фактически преобразуем эти отображенные значения символов в биты, которые можно передавать по сети.

UTF-8 (+)

UTF-8, UTF-16 и UTF-32 - это разные кодировки символов, которые работают с юникодом.

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

8, 16 и 32 соответственно представляют минимальное количество битов, которые будут использоваться для представления данного символа. В таблице ниже приведен пример того, как это может выглядеть:

Base64

Кодирование Base64 немного выходит за рамки кодирования того, что мы традиционно считаем строками или символами - оно позволяет нам кодировать двоичные данные (например, изображения или видео) и представлять их как строки ASCII.

Алгоритм этого кодирования немного сложнее, чем я хотел бы здесь подробно описать, но есть много ресурсов, которые подробно рассматривают это. Одним из явных признаков того, что вы смотрите на строку в кодировке base64, является то, что она заканчивается на = или == - они используются как символы заполнения, чтобы убедиться, что последний байт в закодированной строке завершен (байт имеет 8 бит, поэтому, если исходная строка не имеет нужного количества бит, ей нужно заполнение!)

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

Длина содержимого данных в кодировке base64 обычно примерно на 33% длиннее исходных некодированных данных, поэтому, если вы имеете дело со строками, у которых есть ограничение на максимальную длину, это необходимо учитывать.

Расставание - Практическое применение

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

URL-адреса могут содержать только символы ASCII, поэтому, если они содержат какие-либо символы, отличные от ASCII, их необходимо закодировать в URL-адресе. Например, символ space станет %20 с кодировкой URL. Большинство языков программирования имеют встроенные функции кодирования URL.

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

<meta charset= "utf-8"/>

Однако, если вы отправляете другое значение через заголовки HTTP (например, Content-Type: text/html; charset=utf-16), они будут иметь приоритет над тем, что находится в заголовке HTML. Однако стоит отметить, что спецификация HTML категорически не рекомендует использовать что-либо, кроме UTF-8.