web-dev-qa-db-fra.com

Validation complète du nom de domaine

Existe-t-il un moyen rapide et sale de valider si le nom de domaine complet correct a été entré? N'oubliez pas qu'il n'y a pas de serveur DNS ou de connexion Internet. Par conséquent, la validation doit être effectuée via regex/awk/sed.

Des idées?

19
Riaan

C'est plus difficile aujourd'hui, avec les noms de domaine internationalisés et plusieurs milliers (!) De nouveaux TLD.

La partie facile est que vous pouvez toujours diviser les composants sur ".". 

Vous avez besoin d'une liste de TLD enregistrables. Il y a un site pour ça:

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

Il vous suffit de vérifier celles reconnues par l'ICANN. Notez qu'un TLD enregistrable peut avoir plusieurs composants, tels que "co.uk". 

Ensuite, il y a IDN et punycode. Les domaines sont maintenant au format Unicode. Par exemple,

"xn - nnx388a" est équivalent à "". Les deux sont des TLD valides, incidemment.

Pour le code de conversion punycode, voir " http://golang.org/src/pkg/net/http/cookiejar/punycode.go ".

La vérification de la syntaxe de chaque composant de domaine comporte également de nouvelles règles. Voir RFC5890 à l'adresse http://tools.ietf.org/html/rfc5890

Les composants peuvent être des libellés A (ASCII uniquement) ou Unicode . Les libellés ASCII suivent l'ancienne syntaxe ou commencent par "xn--", auquel cas il s'agit d'une punycode. 

Les règles pour Unicode sont très complexes et sont données dans la RFC5890. Les règles sont conçues pour empêcher des choses telles que le mélange de caractères des ensembles de gauche à droite et de droite à gauche. 

Désolé, il n'y a pas de réponse facile.

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

regex sera toujours au mieux une approximation pour des choses comme celle-ci, et les règles changent avec le temps. la regex ci-dessus a été écrite avec ce qui suit à l'esprit et est spécifique aux noms d'hôtes -

Les noms d'hôte sont composés d'une série d'étiquettes concaténées avec des points . Chaque étiquette comporte de 1 à 63 caractères et peut contenir:

  • les ASCII lettres a-z (sans tenir compte de la casse),
  • les chiffres 0-9,
  • et le trait d'union ('-').

Aditionellement:

  • les étiquettes ne peuvent pas commencer ou se terminer par des traits d'union (RFC 952)
  • les étiquettes peuvent commencer par des chiffres (RFC 1123)
  • la longueur maximale du nom d'hôte ascii, points compris, est de 253 caractères (sans compter le dernier point) ( http://blogs.msdn.com/b/oldnewthing/archive/2012/04/12/10292868.aspx )
  • les traits de soulignement ne sont pas autorisés dans les noms d'hôte (mais sont autorisés dans les autres types DNS)

quelques hypothèses:

  • Le TLD contient au moins 2 caractères et seulement a-z
  • nous voulons au moins 1 niveau au dessus de TLD

résultats: valide/invalide 

  • 911.gov - valide
  • 911 - invalide (pas de TLD)
  • a-.com - invalide
  • -a.com - invalide
  • a.com - valide
  • a.66 - invalide
  • my_Host.com - invalide (undescore)
  • nom-hôte33.w Whatever.co.uk - valide

EDIT: John Rix a fourni un hack alternatif de la regex pour rendre la spécification d’un TLD facultative:

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

EDIT 2: Quelqu'un a demandé une version qui fonctionne en js. la raison pour laquelle cela ne fonctionne pas dans js est parce que js ne prend pas en charge les expressions rationnelles derrière .. ... plus précisément, le code (?<!-) - qui spécifie que le caractère précédent ne peut pas être un trait d'union.

de toute façon, ici il est réécrit sans le lookbehind - un peu plus laid mais pas beaucoup

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

vous pouvez également effectuer un remplacement similaire sur la version de John Rix.

EDIT 3: si vous voulez autoriser les points finaux - ce qui est techniquement autorisé:

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

Je ne connaissais pas la syntaxe des points de fin, mais @ChaimKut les a signalés et j'ai fait des recherches.

L’utilisation de points de fin semble cependant provoquer des résultats quelque peu imprévisibles dans les divers outils avec lesquels je joue, alors je vous conseillerais de faire preuve de prudence.

37
bkr

Cette regex est ce que vous voulez:

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

Cela correspond à votre exemple de domaine (groupa-zone1appserver.example.com ou cod.eu etc ...)

Je vais essayer d'expliquer:

(?=^.{1,254}$) correspond aux noms de domaine (qui peuvent commencer par n’importe quel caractère) dont la longueur est comprise entre 1 et 254 caractères. Il peut également s'agir de 5 254 caractères si nous supposons que co.uk est la longueur minimale.

(^ match de départ

(?: définir un groupe correspondant

(?!\d+\.) le nom de domaine ne doit pas être composé de chiffres, donc 1234.co.uk ou abc.123.uk ne sont pas acceptés, tandis que 1a.ko.uk est oui.

[a-zA-Z0-9_\-] les noms de domaine doivent être composés de mots avec uniquement a-zA-Z0-9_-

{1,63} la longueur de n'importe quel niveau de domaine est au maximum de 63 caractères, (cela pourrait être 2,63)

+ et

(?:[a-zA-Z]{2,})$) la dernière partie du nom de domaine ne doit pas être suivie d'un autre mot et doit être composée d'un mot minimum de 2 caractères a-zA-Z

6
tombolinux

L'expression suivante 

(^((?=^.{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})$)

correspondra

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

mais ne correspond pas:

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
0
Jason Bruce