Двоичное кодирование текста: как работает
Текст в binary, ASCII таблица, как компьютеры хранят текст, конвертация между системами счисления.
Введение
Компьютер не понимает букв, слов или предложений — он понимает только нули и единицы. Всякий раз, когда вы набираете на клавиатуре латинскую «A» или русскую «П», компьютер преобразует этот символ в последовательность битов, и именно эти биты хранятся в памяти, передаются по сети и сохраняются на диске. Как именно происходит это преобразование? Чем кодирование латиницы отличается от кириллицы? Почему эмодзи весят больше, чем буквы? В этой статье разберём двоичное кодирование текста от первой принципы: от бита и байта до Unicode.
Сразу попрактиковаться можно в наших инструментах: текст в двоичный и двоичный в текст.
Биты, байты и системы счисления
Минимальная единица информации — бит. Он может принимать два значения: 0 или 1. Восемь битов образуют байт, который может принимать 256 различных значений (от 00000000 до 11111111, или от 0 до 255 в десятичной системе).
Помимо двоичной (base-2), байты часто записывают в более компактных системах:
- Десятичная (base-10) — привычные цифры от 0 до 255. Например, латинская «A» имеет код 65.
- Шестнадцатеричная (base-16, hex) — цифры 0–9 и буквы A–F. Код «A» — 0x41. Один байт записывается двумя hex-цифрами. Подробнее — в нашей статье о hex кодировании.
- Восьмеричная (base-8) — цифры 0–7. Сегодня почти не используется.
- Двоичная (base-2) — восемь цифр 0/1 на байт. Самый «низкий» уровень представления.
Для числа 65 (буква «A»):
Десятичная: 65
Шестнадцатеричная: 0x41
Восьмеричная: 0101
Двоичная: 01000001ASCII: первая таблица кодирования
В 1963 году Американский национальный институт стандартов опубликовал ASCII — американский стандартный код для обмена информацией. ASCII использует 7 бит, поэтому охватывает 128 символов: латинский алфавит (заглавные и строчные), цифры, основные знаки препинания и управляющие символы (перевод строки, табуляция и т. д.).
Несколько важных кодов ASCII:
| Символ | Десятичный | Hex | Двоичный |
|---|---|---|---|
| пробел | 32 | 0x20 | 00100000 |
| ! | 33 | 0x21 | 00100001 |
| 0 | 48 | 0x30 | 00110000 |
| 9 | 57 | 0x39 | 00111001 |
| A | 65 | 0x41 | 01000001 |
| Z | 90 | 0x5A | 01011010 |
| a | 97 | 0x61 | 01100001 |
| z | 122 | 0x7A | 01111010 |
| ~ | 126 | 0x7E | 01111110 |
| DEL | 127 | 0x7F | 01111111 |
Восьмой бит в байте ASCII изначально оставался свободным и использовался для контроля чётности при передаче. Позже его стали задействовать в расширенных кодировках — прежде всего для кириллицы, греческого, арабского и других алфавитов.
Кодирование кириллицы
ASCII не содержит русских букв, поэтому для кириллицы было создано несколько взаимоисключающих кодировок: KOI8-R, CP866, Windows-1251, ISO 8859-5. Все они используют восьмой бит и кодируют русские буквы кодами от 128 до 255, но по-разному.
| Кодировка | Где использовалась | Особенность |
|---|---|---|
| KOI8-R | Unix, email, FidoNet | При «сбросе» 8-го бита кириллица превращается в латиницу (читаемая транслитерация) |
| CP866 | MS-DOS | Использовалась в консольных программах DOS |
| Windows-1251 | Windows, веб | Стала фактическим стандартом в русскоязычном вебе в 1990-х |
| ISO 8859-5 | Редко | Официальный стандарт ISO, мало где применялся |
В Windows-1251 русская «А» имеет код 0xC0 (192), а русская «я» — 0xFF (255). Буквы идут подряд, что упрощает программирование. Но из-за существования нескольких кодировок пользователи часто видели «кракозябры» — текст, открытый в неправильной кодировке. Окончательно проблема решилась с приходом Unicode и UTF-8. Подробнее — в статье об истории кодировок.
Unicode и UTF-8: современный подход
Unicode присваивает каждому символу уникальный номер (code point). UTF-8 кодирует эти номера переменным числом байтов: 1 для ASCII, 2 для кириллицы и большинства европейских письменностей, 3 для китайского и японского, 4 для эмодзи и исторических письменностей.
Сравним двоичное представление строки «Привет» в разных кодировках:
| Кодировка | Размер | Двоичное представление (hex) |
|---|---|---|
| Windows-1251 | 6 байт | CF F0 E8 E2 E5 F2 |
| UTF-8 | 12 байт | D0 9F D1 80 D0 B8 D0 B2 D0 B5 D1 82 |
| UTF-16 | 12 байт (+2 BOM) | FF FE 1F 04 40 04 38 04 32 04 35 04 42 04 |
| UTF-32 | 24 байт | 1F 04 00 00 40 04 00 00 ... |
В UTF-8 кириллица занимает 2 байта на символ, что в 2 раза больше, чем в Windows-1251. Это плата за универсальность: один и тот же файл может содержать русский, китайский и эмодзи одновременно, без переключения кодировок. Подробнее о UTF-8 — в статье о Unicode и UTF-8.
Как преобразовать текст в двоичный
Алгоритм прост: для каждого символа определить его числовой код в нужной кодировке, представить это число в двоичной системе и при необходимости дополнить нулями слева до нужной длины (7 бит для ASCII, 8 для байта, 16 для UTF-16 code unit и т. д.).
Пример: кодируем «Hi» в ASCII
H = 72 = 01001000
i = 105 = 01101001
Итог: 01001000 01101001Пример: кодируем «Привет» в UTF-8
П = U+041F → UTF-8: D0 9F → 11010000 10011111
р = U+0440 → UTF-8: D1 80 → 11010001 10000000
и = U+0438 → UTF-8: D0 B8 → 11010000 10111000
в = U+0432 → UTF-8: D0 B2 → 11010000 10110010
е = U+0435 → UTF-8: D0 B5 → 11010000 10110101
т = U+0442 → UTF-8: D1 82 → 11010001 10000010
Итог (по байтам):
11010000 10011111 11010001 10000000 11010000 10111000
11010000 10110010 11010000 10110101 11010001 10000010JavaScript: текст в двоичный и обратно
// Текст в двоичный (по байтам UTF-8)
function textToBinary(text) {
const bytes = new TextEncoder().encode(text);
return Array.from(bytes)
.map(b => b.toString(2).padStart(8, '0'))
.join(' ');
}
textToBinary('Hi');
// "01001000 01101001"
textToBinary('Привет');
// "11010000 10011111 11010001 10000000 ..."
// Двоичный в текст
function binaryToText(bin) {
const bytes = bin.split(' ').map(s => parseInt(s, 2));
return new TextDecoder('utf-8').decode(new Uint8Array(bytes));
}
binaryToText('01001000 01101001');
// "Hi"Обратите внимание на использование TextEncoder и TextDecoder. Они работают с UTF-8 по умолчанию и корректно обрабатывают многобайтовые символы. Не пытайтесь делать преобразование через charCodeAt — для эмодзи и суррогатных пар результат будет неверным.
Python: текст в двоичный
def text_to_binary(text):
return ' '.join(format(b, '08b') for b in text.encode('utf-8'))
def binary_to_text(binary):
bytes_list = bytes(int(b, 2) for b in binary.split())
return bytes_list.decode('utf-8')
print(text_to_binary('Hi'))
# '01001000 01101001'
print(text_to_binary('Привет'))
# '11010000 10011111 11010001 10000000 ...'
print(binary_to_text('01001000 01101001'))
# 'Hi'Применения двоичного представления текста
1. Отладка и анализ данных
Если в файле есть непечатные символы или вы подозреваете, что кодировка определена неверно, дамп в двоичном или hex виде поможет разобраться. Hex dump — стандартный инструмент при работе с бинарными форматами.
2. Обучение и понимание
Преобразование текста в двоичный — классическая задача в курсах информатики. Она помогает студентам понять, как компьютер хранит данные, и подготовиться к более сложным темам: сжатию, шифрованию, обработке изображений.
3. Шифрование и обфускация
Иногда двоичное представление используют как простейший способ «спрятать» текст — например, в тривиальных CTF-задачах. Это не настоящая защита, потому что любой может раскодировать строку обратно. Для реальной защиты используйте криптографию.
4. Кодирование в Base64 и Hex
Base64 и hex — это тоже способы представления байтов в виде текста. Но они начинаются с двоичного представления. Подробнее о Base64 читайте в нашей статье о Base64 кодировании, о hex — в материале о hex кодировании.
Биты и символы: длина строки
Длина строки в символах не равна длине в байтах и не равна длине в битах. Например, строка «Привет, мир!»:
- 12 символов
- 12 байт в Windows-1251
- 22 байта в UTF-8 (10 кириллицы × 2 + 2 ASCII)
- 24 байта в UTF-16 + 2 байта BOM = 26 байт
- 48 байт в UTF-32 + 4 байта BOM = 52 байта
- 176 бит в UTF-8 (22 × 8)
Поэтому при работе с текстом важно понимать, в какой кодировке он хранится. Если функция ожидает длину в байтах, а ей передают длину в символах — результат будет некорректным.
Распространённые ошибки
1. Игнорирование кодировки
Многие начинающие разработчики предполагают, что «символ = байт». Для ASCII это так, но для любого другого языка — нет. Если ваш код режет строку посимвольно через индексы байтов, для русского текста он разрежет буквы пополам.
2. Смешивание кодировок
Если вы прочитали файл в Windows-1251 и пытаетесь вывести его в HTML с UTF-8, увидите «кракозябры». Всегда явно указывайте кодировку при чтении и записи.
3. Использование charCodeAt для эмодзи
// НЕПРАВИЛЬНО: вернёт код первого суррогата
'😀'.charCodeAt(0); // 55357
// ПРАВИЛЬНО: вернёт полный code point
'😀'.codePointAt(0); // 128512
// Безопасная длина
[...'😀'].length; // 1, а не 24. Забытый BOM
Если вы сохранили файл в UTF-8 с BOM, а потом склеиваете его с другим содержимым, BOM может оказаться в середине документа и сломать парсинг. В PHP это классическая проблема:session_start() не работает, потому что перед <?php есть невидимые три байта BOM.
Зачем вообще «двоичный текст»
В чистом виде двоичное представление текста (строки нулей и единиц) почти не используется на практике — слишком громоздко. Но как промежуточное звено в обучении и в алгоритмах оно незаменимо. Понимание того, как «A» превращается в 01000001, — основа для понимания всех остальных схем кодирования: Base64, hex, Data URI, шифрования.
Кроме того, двоичное представление полезно для понимания работы побитовых операций: AND, OR, XOR, сдвигов. Эти операции часто применяются в криптографии, обработке изображений и низкоуровневом программировании.
Заключение
Двоичное кодирование текста — это фундамент, на котором построены все более высокие уровни абстракции. Зная, как символ превращается в биты, вы сможете разобраться в любой кодировке, понять, почему возникают «кракозябры», и правильно работать с текстом в любом языке программирования.
Для практической конвертации используйте наши инструменты: текст в двоичный и двоичный в текст. А если хотите глубже погрузиться в тему — читайте наши статьи о Unicode и UTF-8 и об истории кодировок.
Попробуйте эти инструменты
Похожие статьи
Base64 — что это и как работает
Принцип кодирования Base64, алфавит, padding, использование в Data URI, email, API. Примеры кодирования.
URL кодирование: percent-encoding explained
Что такое URL encoding, зарезервированные символы, как кодировать/декодировать URL, частые ошибки.
HTML сущности и кодирование спецсимволов
HTML entities, named vs numeric, XSS защита, кодирование кавычек, амперсандов, угловых скобок.
JWT токен: структура и как декодировать
JSON Web Token: header, payload, signature. Как работает аутентификация JWT, безопасность, декодирование.