Полноценная проверка имени домена - программирование
Подтвердить что ты не робот

Полноценная проверка имени домена

Есть ли быстрый и грязный способ проверки правильности ввода FQDN? Имейте в виду, что DNS-сервер или подключение к Интернету отсутствует, поэтому проверка должна выполняться с помощью regex/awk/sed.

Любые идеи?

4b9b3361

Ответ 1

Сейчас это сложнее, с интернационализированными доменными именами и несколькими тысячами (!) Новых TLD.

Легкая часть состоит в том, что вы все равно можете разбить компоненты на ".".

Вам нужен список регистрируемых TLD. Там сайт для этого:

https://publicsuffix.org/list/effective_tld_names.dat

Вам нужно только проверить признанные ICANN. Обратите внимание, что регистрируемый TLD может иметь более одного компонента, например, "co.uk".

Тогда есть IDN и punycode. Домены теперь Unicode. Например,

"xn-- nnx388a" эквивалентен "臺灣". Кстати, оба из них являются действительными TLD.

Для кода преобразования punycode см. " Http://golang.org/src/pkg/net/http/cookiejar/punycode.go ".

Проверка синтаксиса каждого компонента домена также содержит новые правила. См. RFC5890 по адресу http://tools.ietf.org/html/rfc5890.

Компонентами могут быть либо A-метки (только ASCII), либо Unicode. Символы ASCII либо следуют за старым синтаксисом, либо начинаются с "xn--", и в этом случае они представляют собой штрафную версию строки Unicode.

Правила для Unicode очень сложны и приведены в RFC5890. Правила предназначены для предотвращения таких вещей, как смешивание символов слева-направо и справа налево.

Извините, нет легкого ответа.

Ответ 2

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)

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

Hostnames состоят из серии меток, объединенных с точками. Каждая метка длиной от 1 до 63 символов и может содержать:

  • ASCII-буквы a-z (нечувствительным к регистру),
  • цифры 0-9,
  • и дефис ('-').

Дополнительно:

  • метки не могут начинаться или заканчиваться дефисами (RFC 952)
  • метки могут начинаться с цифр (RFC 1123)
  • максимальная длина имени ascii, включая точки, составляет 253 символа (не считая конечной точки) (http://blogs.msdn.com/b/oldnewthing/archive/2012/04/12/10292868.aspx)
  • подчеркивания недопустимы в именах хостов (но разрешены в других типах DNS)

некоторые предположения:

  • TLD имеет не менее 2 символов и только a-z
  • мы хотим как минимум 1 уровень выше TLD

results: valid/invalid

  • 911.gov - действительный
  • 911 - недействительный (без TLD)
  • a-.com - недействительный
  • -a.com - недействительный
  • a.com - действительный
  • a.66 - недействительный
  • my_host.com - недействительный (undescore)
  • standard-hostname33.whatever.co.uk - действительный

EDIT: Джон Рикс предоставил альтернативный хак регулярного выражения, чтобы уточнить спецификацию TLD:

(?=^.{1,253}$)(^(((?!-)[a-zA-Z0-9-]{1,63}(?<!-))|((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63})$)
  • 911 - действительный
  • 911.gov - действительный

ИЗМЕНИТЬ 2: кто-то попросил версию, которая работает в js. причина, по которой это не работает в js, состоит в том, что js не поддерживает регулярное выражение. в частности, код (?<!-) - который указывает, что предыдущий символ не может быть дефис.

в любом случае, здесь он переписан без lookbehind - немного уродливее, но не намного

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)

вы также можете сделать аналогичную замену версии John Rix.

РЕДАКТИРОВАТЬ 3: если вы хотите разрешить конечные точки - это технически разрешено:

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}\.?$)

Я не был знаком с синтаксисом отстающих точек до тех пор, пока @ChaimKut не указал их, и я провел некоторое исследование

Использование конечных точек, однако, кажется, вызывает несколько непредсказуемых результатов в различных инструментах, с которыми я играл, поэтому я бы посоветовал немного предостережения.

Ответ 3

Это регулярное выражение - это то, что вы хотите:

(?=^.{1,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)

Он соответствует вашему примеру домена (groupa-zone1appserver.example.com или cod.eu и т.д.)

Я попытаюсь объяснить:

(?=^.{1,254}$) соответствует именам доменов (которые могут начинаться с любого char), которые длинные между 1 и 254 char, это также может быть 5 254, если мы предположим, что co.uk - минимальная длина.

(^ начало матча

(?: определить группу соответствия

(?!\d+\.) имя домена не должно быть составлено числами, поэтому 1234.co.uk или abc.123.uk не принимаются в то время как 1a.ko.uk да.

[a-zA-Z0-9_\-] имена доменов должны быть составлены словами только с помощью a-zA-Z0-9 _-

{1,63} длина любого уровня домена не более 63 char (это может быть 2,63)

+ и

(?:[a-zA-Z]{2,})$) конечная часть имени домена не должна сопровождаться каким-либо другим словом и должна состоять из слова минимум 2 char a-zA-Z

Ответ 4

РАССМОТРЕНИЕ № 1:

Обратите внимание, что из-за непринужденных требований в RFC-2181 метки DNS могут состоять из почти любой комбинации символов (однако ограничения по длине все еще существуют):

"Любая двоичная строка, которая может использоваться как метка любой записи ресурса. Реализации DNS-протоколов не должны устанавливать ограничений на метки, которые могут быть использованы. В частности, DNS-серверы не должны отказываться от обслуживания зоны, потому что он содержит метки, которые могут быть неприемлемыми для некоторых клиентских программ DNS". (https://tools.ietf.org/html/rfc2181#section-11)

РАССМОТРЕНИЕ # 2:

"Существует дополнительное правило, которое по существу требует, чтобы имена доменов верхнего уровня не были все-числовыми" (https://tools.ietf.org/html/rfc3696#section-2)

Учитывая эти два соображения, правильное регулярное выражение выглядит так:

/^(?!:\/\/)(?=.{1,255}$)((.{1,63}\.){1,127}(?![0-9]*$)[a-z0-9-]+\.?)$/i

См. демонстрацию @http://regexr.com/3g5j0

Ответ 5

Следующее выражение

(^((?=^.{4,253}$)(((http){0,1}|(http){0,1}|(ftp){0,1}|(ws){0,1})(s{0,1}):\/\/){0,1})((((?!-)[\pL0-9\-]{1,63})(?<!-)(\.)){1,})(((?!-)[a-z0-9\-]{1,63})(?<!-)((\/{0,1}[\pL\pN?=\-]*)+){1})$)

будет соответствовать

https://www.tes1t.com/lets/to?878932572
https://www.test.co.uk/lets/to?878932572
http://www.test.com/lets/to?878932572
http://www.test.co.uk/lets/to?878932572
ftp://www.test.com/lets/to?878932572
subdomain.test.com/lets/to?878932572
subdomain.test.com/lets/to?878932572
subdomain.subdomain.test.net/lets/to?878932572

sub-domain.test.net/lets/to?878932572
sub-domain.test.net/lets-go/to?878932572
www.test.net/lets/to?878932572
www.test-test.com/
www.test-test.com

subdomain.subdomainsubdomainsuèdomainsubdomainsubdomainsubdomainsubdomain.net/let2s/to?=878932572

www.test-test.co.uk
http://www.test-test-.com/test
www.test-teèst.co.uk/lets
www.test-test.co.uk/lets/
www.test-test.co.uk/lets/to?
test-test.co.uk/lets/to?
test-test.co.uk/lets/
test-test.co.uk/lets
test-test.co.uk
http://test.com/lets/to?878932572
https://test.com/lets/to?878932572
ftp://test.com/lets/to?878932572
ftps://test.com/lets/to?878932572
ws://test.com/lets/to?878932572aa
wss://test.com/lets/to?=878932572bar
test.com

subdomain.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.khbdomainsubdomainsubdomain.test.net/lets/to?87893257

но не совпадают:

www.-test-fail-.com
www.-test-fail.com
-test-fail.com
test-fail-.com

subdomain.subdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainubdomainsubdomainsubdomain.test.net/lets/to?878932572

subdomain.subdomainsubdomainsubdcnvcnvcnofhfhghgfhvnhj-mainsubdomainsubdohhghghghfhgffgjh-gfhfdhfdghmainsubdocgvhngvnbnbmghghghaihgfjgfnfhfdghgsufghgghghhdfjgffsgfbdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomain.test.net/lets/to?878932572

subdomain.test.test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test.khbdomainsubdomainsubdomain.test.net/lets/to?87893257

Ответ 6

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

^(?!.*?_.*?)(?!(?:[\d\w]+?\.)?\-[\w\d\.\-]*?)(?![\w\d]+?\-\.(?:[\d\w\.\-]+?))(?=[\w\d])(?=[\w\d\.\-]*?\.+[\w\d\.\-]*?)(?![\w\d\.\-]{254})(?!(?:\.?[\w\d\-\.]*?[\w\d\-]{64,}\.)+?)[\w\d\.\-]+?(?<![\w\d\-\.]*?\.[\d]+?)(?<=[\w\d\-]{2,})(?<![\w\d\-]{25})$

Доказательство и объяснение: https://regex101.com/r/FLA9Bv/9

При проверке доменов можно выбрать один из двух подходов.

Соответствие полному доменному имени (теоретическое определение, редко встречающееся на практике):

  • длина не более 253 символов (согласно RFC-1035/3.1, RFC-2181/11)
  • не более 63 символов на этикетку (согласно RFC-1035/3.1, RFC-2181/11)
  • разрешены любые символы (согласно RFC-2181/11)
  • TLD не могут быть полностью числовыми (согласно RFC-3696/2)
  • Полные доменные имена могут быть записаны в полной форме, которая включает корневую зону (конечная точка)

Практическое/консервативное сопоставление FQDN (практическое определение, ожидаемое и поддерживаемое на практике):

  • соответствие книг со следующими исключениями/дополнениями
  • допустимые символы: [a-zA-Z0-9.-]
  • метки не могут начинаться или заканчиваться дефисами (согласно RFC-952 и RFC-1123/2.1)
  • Минимальная длина TLD - 2 символа, максимальная длина - 24 символа в соответствии с текущими записями.
  • не соответствует конечной точке