ASCII: что это и где используется

8 ноября 2026 г.

Открываете текстовый редактор и видите в начале файла незнакомые символы. Или получаете от коллеги письмо, где вместо текста цепочка символов вроде #5$#@!$&%. Или смотрите дамп файла и видите 0D 0A в конце каждой строки. Всё это следы одного стандарта, который появился раньше интернета, персональных компьютеров и даже графических мониторов. Стандарт называется ASCII.

Что такое ASCII и откуда он взялся

ASCII расшифровывается как American Standard Code for Information Interchange, американский стандартный код для обмена информацией. Первая версия была опубликована в 1963 году как ASA X3.4-1963, позже стандарт переиздавался в редакциях ANSI X3.4-1968, -1977 и -1986.

История началась ещё раньше. В мае 1961 года инженер IBM Боб Бемер предложил Американской ассоциации по стандартам создать единый код для обмена информацией между вычислительными машинами. Задача была практической: у каждого производителя была своя таблица символов, и данные приходилось перекодировать вручную при переносе с одной машины на другую.

Здесь важно понимать контекст. Стандарт создавался в мире телетайпов и перфокарт, а не в мире текстовых редакторов. Отсюда и главное техническое решение: код семибитный. Семь бит хватает для 128 значений, а восьмой бит на перфоленте можно было отдать под проверку чётности, то есть под обнаружение ошибок при передаче. Отправлять восьмой бит по линии было дорого, и от него отказались.

Обратите внимание на формулировку: восьмой бит не был частью символа ASCII. Это отдельный механизм контроля ошибок, использовавшийся на телеграфных линиях. На восьмибитных компьютерах, где проверки чётности не было, этот бит обычно просто выставлялся в ноль. Путаница между «ASCII это семь бит» и «ASCII это восемь бит» до сих пор встречается, хотя в стандарте всё однозначно.

128 символов и как устроена таблица

Семь бит дают ровно 128 кодовых позиций, от 0 до 127. Таблица разделена на четыре группы по 32 символа, и деление это не условность: в каждой группе ровно 16 печатных и 16 непечатных символов, поэтому в коде проще ориентироваться, чем в общей таблице на 256 позиций.

  • 0x00–0x1F, коды с 0 по 31: управляющие символы. Их 32, и на них приходится весь «невидимый» синтаксис текстовых форматов;
  • 0x20–0x3F, коды с 32 по 63: пробел, знаки препинания и цифры от 0 до 9;
  • 0x40–0x5F, коды с 64 по 95: знак @, заглавные латинские буквы A–Z и часть знаков препинания;
  • 0x60–0x7F, коды с 96 по 127: строчные латинские буквы a–z, остальные знаки препинания и служебный код 127.

Печатных символов в таблице 95, и это числа с 32 по 126 включительно. Пробел имеет код 32, восклицательный знак 33, цифра 0 код 48, заглавная A код 65, строчная a код 97, а последний печатный символ, тильда, код 126. Код 127 не печатный: это DEL, удаление, оставшееся от телетайпной эпохи.

Как выглядят коды ASCII
Символ   Десятичное   Шестнадцатеричное   Двоичное
пробел        32           0x20         00100000
!             33           0x21         00100001
0             48           0x30         00110000
A             65           0x41         01000001
Z             90           0x5A         01011010
a             97           0x61         01100001
z            122           0x7A         01111010
~            126           0x7E         01111110

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

Управляющие символы: CR, LF, TAB, ESC

Половина таблицы приходится на управляющие символы, и именно они объясняют, почему в текстовых файлах встречаются невидимые конструкции. Каждый из них задаёт не букву, а действие.

  • NUL, код 0: нулевой байт, признак конца строки в C и основа для строк с нулевым терминатором;
  • TAB, код 9: горизонтальная табуляция, переход к позиции с шагом 8;
  • LF, код 10: перевод строки, тот самый символ, который в языках программирования записывают как \n;
  • VT, код 11: вертикальная табуляция;
  • FF, код 12: перевод страницы или очистка экрана;
  • CR, код 13: возврат каретки, который записывают как \r;
  • ESC, код 27: экранирование, начало управляющих последовательностей терминала;
  • DEL, код 127: удаление символа.

Почему перевод строки записывается именно как \n, если его код равен 10? Это не совпадение и не путаница. Значение \n в языках C, Java, JavaScript и Python исторически соответствует коду LF, то есть десятичному 10 в таблице ASCII. Управляющая последовательность буквально означает «символ с номером 10», и то, что десятичное запись выглядит как n, объясняется тем, что LF десятичная десятка, а буква n рядом с ней стоит в старой системе счисления счислений, использовавшейся в ранних системах.

Второй управляющий символ, который встречается чаще всего, это CR с кодом 13, записываемый как \r. Назначение у него буквальное: в телетайпном устройстве CR возвращала каретку в начало строки, а LF сдвигала бумагу на одну строку вверх. Это два отдельных механизма, и в системах, где печатающая машинка была единственным выводом, они вызывались по отдельности.

Отсюда две договоренности, которые живут до сих пор. В системах Unix конец строки обозначается одним символом LF, то есть 0x0A. В системах Windows используется пара CR LF, то есть 0x0D 0x0A, где CR возвращает каретку, а LF опускает её на новую строку. Из-за этого файлы, созданные в одной системе и прочитанные в другой, иногда выглядят как одна длинная строка: символ LF пролетает мимо, потому что курсор не возвращается в начало.

Как выглядят переводы строк в дампе
Unix (LF):      68 65 6C 6C 6F 0A          hello.
Windows (CR LF): 68 65 6C 6C 6F 0D 0A      hello.
Старый Mac (CR): 68 65 6C 6C 6F 0D          hello.

0A = перевод строки, 0D = возврат каретки
В тексте видно: "hello." на одной строке, "hello" с последующим переводом

Ещё один управляющий код, который встречается чаще, чем кажется, это TAB. В текстовых форматах с выравниванием, таких как TSV или формат Makefile, символ с кодом 9 служит разделителем колонок или отступом. Поэтому файл, где вместо табуляции стоят пробелы, может разъезжаться при открытии в другой программе.

ASCII внутри современных кодировок

Сейчас ASCII используется почти исключительно как фундамент. Первая его большая заслуга в том, что первые 128 кодовых позиций таблицы Unicode совпадают с ASCII символ в символ. Именно поэтому ASCII считается подмножеством Unicode, и именно поэтому UTF-8 оказался обратно совместимым с ASCII.

Совместимость выглядит так. Символ с кодом меньше 128 в UTF-8 записывается ровно одним байтом с тем же значением, что и в ASCII. Символ с кодом 128 и выше записывается двумя, тремя или четырьмя байтами. Получается, что файл, в котором нет ни одного символа выше U+007F, побайтово одинаков в ASCII и в UTF-8, а программа, читающая только ASCII, продолжит работать с новыми файлами без изменений. Подробнее о том, как устроено преобразование кодовых точек в байты, рассказано в статье про UTF-8 и Unicode.

  • ASCII это подмножество Unicode: первые 128 позиций совпадают один в один;
  • UTF-8 обратно совместим с ASCII: символы ниже U+0080 занимают ровно один байт;
  • Windows-1251 и KOI8-R тоже сохраняют ASCII в первых 128 позициях, добавляя кириллицу в верхней части таблицы;
  • любая современная кодировка, претендующая на совместимость с ASCII, держит латиницу, цифры и базовую пунктуацию на тех же местах.

Где ASCII встречается сегодня

Стандарт, которому шестьдесят лет, не исчез и не устарел. Он живёт в местах, где важна не красота записи, а предсказуемость.

  • протоколы и заголовки. HTTP-заголовки, большинство команд SMTP, формат DNS построены на ASCII, и это позволяет разбирать их побайтово без сложных парсеров;
  • исходный код и конфигурационные файлы. Скрипты, Makefile, requirements.txt, конфиги nginx и systemd пишутся в ASCII, чтобы работать одинаково в любой среде;
  • имена файлов. Ограничение ASCII в именах избавляет от проблем с кодировками при переносе между системами;
  • форматы данных. CSV, JSON Schema, robots.txt, sitemap.xml используют ограниченный набор символов;
  • ASCII-арт. Баннеры из символов, рисунки в комментариях к коду и в README, оформление вывода в терминале;
  • аппаратные протоколы. Многие микроконтроллеры и промышленные устройства работают с ограниченными наборами символов по UART;
  • учебные материалы. Кодировка Морзе, например, использует только латинские буквы, цифры и знаки препинания, и потому прекрасно ложится на таблицу ASCII.

Сделать баннер из символов для вывода в терминале или для README можно через генератор ASCII-арта. Там же рядом лежит переводчик азбуки Морзе, который работает по той же логике замены символов, только набор знаков другой.

Кириллицы в ASCII нет, и вот что из этого следует

Главное практическое ограничение: в таблице 128 символов нет ни одной русской буквы. Латиница, цифры, пунктуация и управляющие коды, то есть всё, что там есть. Исторически это нормально, потому что стандарт создавался в англоязычной среде, но сегодня из этого вырастают конкретные проблемы.

Первый вариант, добавить кириллицу в саму таблицу, был отвергнут: стандарт на то и стандарт, что его не переделывают на ходу. Второй вариант, расширить таблицу в восьмибитном варианте, оказался удачным, и так появились кодировки вроде Windows-1251 и KOI8-R, где первые 128 позиций остались ASCII, а кириллица заняла верхнюю часть таблицы.

Кириллица в Windows-1251
Код   Символ   ASCII на этом месте
0xC0     А      не определён
0xD8     Ё      не определён
0xDF     Я      не определён
0xE0     а      не определён
0xF8     ё      не определён
0xFF     я      не определён

Позиции 0x00–0x7F в Windows-1251 совпадают с ASCII один в один.

Третий вариант, сделать таблицу на 1 114 112 позиций и хранить символы в UTF-8, стал тем решением, к которому пришли все. Но у него появилось побочное следствие: если программа читает файл в ASCII, она не просто «не увидит» кириллицу, она может испортить файл целиком. Одна русская буква в UTF-8 занимает два байта, и если один из них приходится на управляющий код, получается совсем неожиданный эффект.

Неразборчивые символы в файле: откуда они берутся

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

  • файл в UTF-16, прочитанный как однобайтовый. Между символами появляются нули, потому что в UTF-16 каждый символ занимает два байта;
  • файл в UTF-8 с BOM, где первые три байта EF BB BF интерпретированы как отдельные символы и дают невидимый хвост в начале;
  • файл в UTF-8 без BOM, прочитанный как windows-1251. Получается классическая картинка из двух латинских букв на месте одной русской;
  • двоичный файл, открытый в текстовом редакторе. Там действительно нет текста, есть байты;
  • файл, где вместо переводов строк оказались неразрывные пробелы или неразрывный дефис, вставленные при копировании из веба.

Определить кодировку файла по первым байтам и сравнить варианты чтения помогает детектор кодировки.

Как читать дамп и не путать байты с символами

Дамп файла показывает байты, а не символы, и это главный источник непонимания. В дампе каждый байт занимает две шестнадцатеричные цифры, потому что в байте ровно 256 значений, а шестнадцатеричная цифра даёт 16. Один байт всегда умещается ровно в пару hex-цифр, и это позволяет читать дамп на глаз.

Чтобы разложить такие значения на составляющие, помогает инструмент разбора HEX в RGB: он показывает десятичное значение каждого байта и его долю в цвете, а заодно наглядно демонстрирует правило «один байт равен двум hex-цифрам».

И отдельно про то, как в дампе выглядят escape-последовательности. Если в тексте программы написано \t, это не два символа «обратный слэш и t», а один символ с кодом 9. То же самое с \n, \r и любым другим именованным кодом. Разница видна на уровне байтов: в файле escape-последовательность занимает два байта, а управляющий символ один.

ASCII против Unicode: в чём разница

Путаница между этими терминами возникает постоянно, хотя они отвечают на разные вопросы. ASCII это конкретная таблица на 128 символов с конкретным набором управляющих кодов. Unicode это соглашение о том, какие символы вообще существуют в мире, с номерами от U+0000 до U+10FFFF. UTF-8 это способ упаковать эти номера в байты.

  • ASCII: 128 символов, 7 бит, только латиница и управляющие коды, стандарт 1963 года;
  • Unicode: более 1,1 миллиона кодовых позиций, все письменности мира, стандарт с 1991 года;
  • UTF-8: кодировка, где символ занимает от 1 до 4 байт в зависимости от номера;
  • ASCII входит в Unicode как подмножество, поэтому любая программа, работавшая с ASCII, работает и с UTF-8 для латиницы.

Отсюда практический вывод: если задача в том, чтобы понять, что за символы в конкретном файле, начинать стоит с определения кодировки, а не с гадания по внешнему виду. Стандарт ASCII полезен как точка отсчёта, от которой удобно считать.

Типичные ошибки

  • считать, что ASCII это восемь бит. В стандарте семь бит, а восьмой использовался под проверку чётности на перфоленте;
  • путать 95 и 128. Печатных символов 95, с кодами от 32 до 126, а управляющих 33, с кодами 0–31 и 127;
  • забыть про регистр в кодах букв. Заглавная A это 65, строчная a это 97, разница ровно 32;
  • полагать, что \n это буква n. Это управляющий символ с кодом 10, и в дампе он занимает один байт, тогда как escape-последовательность в исходном коде занимает два;
  • ожидать, что ASCII-файл с кириллицей будет работать. Кириллицы в стандарте нет вообще;
  • писать в HTML код символа, не проверив, что он помещается в ASCII. Символы с кодом выше 127 в HTML записываются как числовые ссылки или как именованные сущности, иначе разметка ломается.

Частые вопросы

Чем ASCII отличается от UTF-8?

Размером и возможностями. ASCII описывает 128 символов в семи битах, из которых 95 печатных, и ничего кроме латиницы. UTF-8 описывает более миллиона кодовых точек Unicode, используя от одного до четырёх байт на символ. При этом ASCII полностью содержится в UTF-8, и текст, где нет символов выше U+007F, в обеих кодировках выглядит одинаково.

Почему в ASCII только 128 символов?

Так сложилось исторически и технически. Стандарт создавался для телеграфных линий и перфокарт, где каждый символ стоил отдельный бит времени передачи, и экономия была важнее удобства. Восьмой бит отводился под проверку чётности при передаче, поэтому в сам символ он не входил. Добавление новых символов в таблицу обошлось бы в изменение стандарта, а это оказалось проще сделать через отдельные расширения.

Что значит 0x20 и почему это не 32?

0x20 это просто запись того же самого числа в шестнадцатеричной системе: 2 умножить на 16 плюс 0, итого 32 в десятичной. Разные записи одного числа. В дампах файлов принято показывать байты в hex, потому что так они выравниваются в колонки и читаются парами, а десятичные значения удобнее считать в уме.

Почему означает 10, а не букву n?

Потому что запись \n обозначает символ с десятичным номером 10, а это код перевода строки в таблице ASCII. Буква n рядом с десяткой стоит в старой системе счисления, которой пользовались до распространения двоичной записи, и это совпадение со временем закрепилось в синтаксисе языков программирования. Рядом живут и другие имена: \t это код 9, \r это код 13, \0 это код 0.

Можно ли записать кириллицу в ASCII?

Нет, в таблице просто нет ни одной русской буквы. Попытка записать её приведёт либо к ошибке, либо к тому, что на выходе получится совсем другой символ. Для русского текста нужна кодировка с кириллицей: Windows-1251, KOI8-R или, что предпочтительнее сегодня, UTF-8. Про разницу между Unicode и UTF-8 и про то, как не получить кракозябры, стоит почитать отдельно.

Почему в файле вместо текста непонятные символы?

Скорее всего, файл читается не в той кодировке, в какой записан. Определить кодировку по первым байтам и сравнить результаты чтения помогает детектор кодировки. Если же вместо текста видны настоящие непечатные символы, скорее всего, файл просто двоичный, и открывать его текстовым редактором не нужно.

Правило, которое снимает большинство вопросов: помните, что ASCII это 128 позиций, 95 из которых печатные, с кодами от 32 до 126, а всё, что ниже 32, это управляющие символы. Всё остальное, что вы видите в дампе, стоит проверять по кодам, а не на глаз.

Читайте также