Punycode
Punycode — это стандарт кодирования интернационализированных доменных имён (IDN), содержащих символы национальных алфавитов, в последовательность символов ASCII, пригодную для использования в системе доменных имён (DNS). Разработан для обеспечения совместимости нелатинских символов (например, кириллицы, арабского, китайского) с существующей инфраструктурой DNS, которая исторически поддерживает только латинские буквы, цифры и дефис. Punycode определён в документе RFC 3492 (2003 год) и является частью механизма IDNA (Internationalized Domain Names in Applications).
История и предпосылки создания
До появления Punycode доменные имена могли содержать только символы латинского алфавита (A–Z), цифры (0–9) и дефис. Это ограничение было заложено в протоколах DNS, разработанных в 1980-х годах. С ростом глобализации интернета возникла необходимость использовать доменные имена на языках, не использующих латиницу, — например, на русском, арабском, китайском или хинди.
В 1998 году была создана рабочая группа IETF (Internet Engineering Task Force) по стандартизации интернационализированных доменных имён. Предлагалось несколько подходов к кодированию, включая использование UTF-8 напрямую, но это требовало изменения протоколов DNS. Более практичным решением стало преобразование нелатинских символов в ASCII-совместимую строку, которая могла бы обрабатываться существующими DNS-серверами без модификаций. В 2003 году был принят стандарт RFC 3492, описывающий алгоритм Punycode, разработанный Адамом Костюком (Adam Costello).
Принцип работы
Punycode использует алгоритм кодирования, основанный на смешанном представлении (mixed-radix) и адаптивном сжатии. Основная цель — представить строку Unicode (например, доменное имя на кириллице) в виде последовательности ASCII-символов, которая начинается с префикса «xn--». Этот префикс сигнализирует браузерам и DNS-клиентам, что последующая часть закодирована с помощью Punycode.
Алгоритм кодирования
- Разделение символов. Строка Unicode делится на две группы: «основные» (basic) — символы ASCII (буквы, цифры, дефис), и «дополнительные» (non-basic) — все остальные символы, включая буквы национальных алфавитов.
- Кодирование дополнительных символов. Для каждого дополнительного символа определяется его кодовая позиция в Unicode. Затем эти коды преобразуются в последовательность ASCII-символов с использованием алгоритма, напоминающего кодирование чисел в системе с переменным основанием (bootstring). На каждом шаге алгоритм адаптивно выбирает основание системы счисления, чтобы минимизировать длину выходной строки.
- Формирование результата. Результат состоит из:
- префикса «xn--»;
- основных символов (если они есть) в исходном порядке;
- дефиса (если были основные символы);
- закодированной последовательности, представляющей дополнительные символы.
Пример
Рассмотрим доменное имя пример.рф (кириллица). В Punycode оно будет выглядеть как xn--e1afmkfd.xn--p1ai. Здесь:
- «xn--e1afmkfd» — закодированная часть для «пример»;
- «xn--p1ai» — закодированная часть для «рф» (домен верхнего уровня).
Декодирование происходит в обратном порядке: Punycode-строка распознаётся по префиксу «xn--», затем алгоритм восстанавливает исходные символы Unicode.
Технические детали
Формат IDN
Интернационализированное доменное имя (IDN) в DNS хранится в виде ASCII-строки, закодированной с помощью Punycode. Например, домен «moscow.ru» на кириллице (например, «москва.ru») будет преобразован в «xn--80adxhks.ru». При этом метка (часть домена между точками) не может превышать 63 символа в ASCII-представлении, что накладывает ограничение на длину исходного имени.
Ограничения
- Punycode не поддерживает все символы Unicode. Некоторые символы, например, управляющие или недопустимые для доменов (пробелы, знаки препинания), не могут быть закодированы.
- Алгоритм чувствителен к регистру: буквы в Punycode-строке обычно записываются в нижнем регистре, хотя DNS не различает регистр.
- Длина закодированной строки может быть значительно больше исходной, особенно для языков с большим количеством символов за пределами ASCII (например, китайского).
Применение
Punycode используется в следующих контекстах:
- Регистрация доменных имён. Регистраторы доменов (например, в зонах .рф, .рус, .дети и других национальных доменах) автоматически преобразуют вводимые пользователем нелатинские имена в Punycode для хранения в DNS.
- Веб-браузеры. Современные браузеры (Chrome, Firefox, Safari, Edge) поддерживают IDN и отображают Punycode-строки в адресной строке как исходные символы Unicode. Однако для предотвращения фишинговых атак (омоглифов) браузеры могут показывать Punycode-представление, если домен содержит смешанные алфавиты (например, латиницу и кириллицу) или если символы выглядят как латинские, но таковыми не являются. Это явление известно как «IDN homograph attack».
- Электронная почта. Протокол SMTP требует, чтобы доменные имена в адресах электронной почты были в ASCII, поэтому Punycode применяется для кодирования нелатинских доменов в почтовых адресах.
- Протоколы передачи данных. Punycode используется в протоколах, работающих поверх DNS, таких как HTTP, HTTPS, FTP, при обращении к ресурсам по IDN.
Критика и проблемы
Фишинг и омоглифы
Основная критика Punycode связана с возможностью визуальной подмены символов (омоглифы). Например, кириллическая буква «а» (U+0430) визуально неотличима от латинской «a» (U+0061). Злоумышленники могут регистрировать домены, которые выглядят идентично легитимным, но в Punycode-представлении отличаются. Например, домен «xn--pple-43d.com» может отображаться как «apple.com» (с кириллической «а»), что используется для фишинга. В ответ на это браузеры внедрили механизмы, показывающие Punycode-строку в адресной строке, если домен содержит смешанные алфавиты или подозрительные символы.
Ограничения по длине
Punycode увеличивает длину доменного имени, что может привести к превышению лимита в 63 символа на метку. Это особенно критично для языков с многобайтовыми символами (например, китайский, японский), где одно слово может занимать несколько символов Unicode.
Несовместимость с некоторыми системами
Старые версии операционных систем, почтовых клиентов или DNS-серверов могут не поддерживать IDN и Punycode, что приводит к ошибкам при вводе доменов на национальных языках. Однако с 2010-х годов большинство современных систем корректно обрабатывают Punycode.
Интересные факты
- Punycode не является шифрованием или сжатием в традиционном смысле — это просто кодирование, обратимое и детерминированное.
- Алгоритм Punycode может кодировать любую строку Unicode, но на практике используется только для доменных имён.
- Домен верхнего уровня .рф (Российская Федерация) был запущен в 2010 году и стал одним из первых национальных доменов на кириллице, полностью поддерживающих Punycode.
- В 2017 году был зарегистрирован домен «xn--80aswg.xn--p1ai» (кириллический «сайт.рф»), который стал одним из самых коротких IDN-доменов.
Источники
- RFC 3492 — Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA).
- RFC 5890 — Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework.
- RFC 5891 — Internationalized Domain Names in Applications (IDNA): Protocol.
- «Punycode: The Encoding of Internationalized Domain Names» — статья в журнале «IEEE Internet Computing», 2004.
- Документация ICANN по интернационализированным доменным именам.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →


