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-символы как есть, а остальные кодируем специальным образом.
Пример: домен москва.рф
- Выделяем ASCII-часть — её нет, все символы кириллица
- Кодируем Unicode-символы в числа и сжимаем по алгоритму
- Добавляем префикс
xn--(сигнал для DNS) - Результат:
xn--80adxhks.xn--p1ai
Для домена test-тест.ru:
- ASCII-часть:
test- - Кодируем
тест→-90ais - Склеиваем:
test--90ais - Добавляем префикс:
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-инфраструктурой. Технология работает незаметно, но знание принципов поможет избежать проблем при настройке серверов и защитит от фишинговых атак.