Открыть сервис

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.

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

  1. Разделение символов. Строка Unicode делится на две группы: «основные» (basic) — символы ASCII (буквы, цифры, дефис), и «дополнительные» (non-basic) — все остальные символы, включая буквы национальных алфавитов.
  2. Кодирование дополнительных символов. Для каждого дополнительного символа определяется его кодовая позиция в Unicode. Затем эти коды преобразуются в последовательность ASCII-символов с использованием алгоритма, напоминающего кодирование чисел в системе с переменным основанием (bootstring). На каждом шаге алгоритм адаптивно выбирает основание системы счисления, чтобы минимизировать длину выходной строки.
  3. Формирование результата. Результат состоит из:
  • префикса «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 →