ttools
punycodeдоменыкодированиеинтернет

Punycode: как работают домены на русском и закодировать адрес

Разбираемся, как браузер переводит кириллицу в домене в ASCII-код и почему xn-- в начале URL — это нормально

Домены с кириллицей выглядят привычно в адресной строке, но серверы понимают только латиницу и ASCII-символы. Браузер автоматически превращает президент.рф в xn--d1abbgf6aiiy.xn--p1ai, и пользователь этого не замечает. Разбираемся, как работает эта магия и зачем нужен Punycode.

Почему домены не могут содержать кириллицу

DNS-система проектировалась в 1980-х, когда интернет существовал только в англоязычной среде. Протоколы работают с ASCII — набором из 128 символов: латинские буквы, цифры, дефис. Русские буквы, китайские иероглифы или арабская вязь туда не входят.

Когда в 2000-х потребовалось добавить национальные алфавиты, инженеры столкнулись с проблемой: менять всю инфраструктуру DNS невозможно. Решение — кодировать Unicode-символы в ASCII-последовательность, которую старые серверы обработают без изменений.

Так появился стандарт IDN (Internationalized Domain Names) и алгоритм Punycode. Браузер видит кириллицу, преобразует её в ASCII-код с префиксом xn--, отправляет запрос на сервер. Пользователь продолжает видеть понятный адрес, а инфраструктура работает по старым правилам.

Как устроен Punycode

Алгоритм преобразует Unicode-строку в ASCII через несколько этапов. Базовый принцип: берём все ASCII-символы как есть, а остальные кодируем специальным образом.

Пример: домен москва.рф

  1. Выделяем ASCII-часть — её нет, все символы кириллица
  2. Кодируем Unicode-символы в числа и сжимаем по алгоритму
  3. Добавляем префикс xn-- (сигнал для DNS)
  4. Результат: xn--80adxhks.xn--p1ai

Для домена test-тест.ru:

  1. ASCII-часть: test-
  2. Кодируем тест-90ais
  3. Склеиваем: test--90ais
  4. Добавляем префикс: xn--test--90ais

Двойной дефис -- отделяет оригинальные ASCII-символы от закодированной части. Если в домене только кириллица, перед закодированной частью стоит просто дефис.

Как закодировать домен вручную

Браузеры делают преобразование автоматически, но иногда нужно получить Punycode-версию вручную — для конфигурации сервера, DNS-записей или API-запросов.

В JavaScript:

// Кодирование
const domain = 'президент.рф';
const encoded = domain.split('.').map(part => {
  return new URL(`http://${part}`).hostname;
}).join('.');
console.log(encoded); // xn--d1abbgf6aiiy.xn--p1ai

// Декодирование
const punycode = 'xn--80adxhks';
console.log(decodeURIComponent(punycode)); // всё ещё punycode
// Нужна библиотека punycode.js или метод toUnicode

В Python:

domain = "москва.рф"
encoded = domain.encode('idna').decode('ascii')
print(encoded)  # xn--80adxhks.xn--p1ai

# Декодирование
decoded = encoded.encode('ascii').decode('idna')
print(decoded)  # москва.рф

В PHP:

$domain = 'тест.рф';
$encoded = idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
echo $encoded; // xn--e1aybc.xn--p1ai

$decoded = idn_to_utf8($encoded);
echo $decoded; // тест.рф

Библиотеки используют стандартную реализацию RFC 3492, поэтому результат одинаковый во всех языках.

Частые проблемы с IDN-доменами

Фишинг через похожие символы. Латинская a и кириллическая а выглядят одинаково, но имеют разные коды. Злоумышленники регистрируют аpple.com (первая буква кириллическая) вместо apple.com. Браузеры борются с этим: показывают Punycode-версию, если домен содержит символы из разных алфавитов.

Проблемы с SSL-сертификатами. Центры сертификации требуют Punycode-версию домена в CSR-запросе. Если указать кириллицу, валидация провалится. Всегда проверяйте, какую версию ожидает система.

Некорректная обработка в коде. Не все библиотеки автоматически конвертируют IDN. Например, curl в старых версиях не понимает кириллические домены без флага --idn:

curl https://президент.рф  # ошибка
curl --idn https://президент.рф  # работает

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

Зачем знать Punycode-версию домена

В большинстве случаев браузер всё делает сам, но есть ситуации, где нужна ASCII-версия:

  • Настройка DNS-записей (многие панели требуют xn-- формат)
  • API-запросы к сервисам без поддержки Unicode
  • Конфигурация веб-серверов (Nginx, Apache)
  • Email-адреса на доменах с кириллицей
  • Debugging сетевых запросов (в логах всегда Punycode)

Если получаете ошибку «invalid domain» при работе с кириллическим доменом — попробуйте передать Punycode-версию.

Инструменты для работы с кодированием

Для быстрого преобразования доменов и проверки других видов кодирования пригодятся онлайн-инструменты. URL Encoder/Decoder поможет закодировать кириллические параметры в ссылках, а Base64 Encoder/Decoder — для работы с бинарными данными в текстовом виде. Если нужно посмотреть, как выглядит строка в разных кодировках, используйте Text to ASCII/Hex Converter.

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

Инструменты по теме