Проверьте доменные имена в соответствии со стандартом RFC 1035 в Java - PullRequest
0 голосов
/ 01 июля 2019

Я пытаюсь написать код, чтобы проверить правильность доменных имен согласно стандарту rfc 1035 или нет.RFC 1035 (https://tools.ietf.org/html/rfc1035) стандарт имеет следующие критерии для доменных имен:

<domain> ::= <subdomain> | " "

<subdomain> ::= <label> | <subdomain> "." <label>

<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]

<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>

<let-dig-hyp> ::= <let-dig> | "-"

<let-dig> ::= <letter> | <digit>

<letter> ::= any one of the 52 alphabetic characters A through Z in
upper case and a through z in lower case

<digit> ::= any one of the ten digits 0 through 9

Note that while upper and lower case letters are allowed in domain
names, no significance is attached to the case.  That is, two names with
the same spelling but different case are to be treated as if identical.

The labels must follow the rules for ARPANET host names.  They must
start with a letter, end with a letter or digit, and have as interior
characters only letters, digits, and hyphen.  There are also some
restrictions on the length.  Labels must be 63 characters or less.

Я написал следующий фрагмент кода на Java, чтобы проверить, является ли имя домена действительным в соответствии с rfc 1035 или нет.

//DomainUtils.java
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class DomainUtils {

   private static Pattern pDomainNameOnly1;
   private static Pattern pDomainNameOnly2;

   private static final String DOMAIN_NAME_PATTERN_CHK_1 = "^(?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)$";
   private static final String DOMAIN_NAME_PATTERN_CHK_2 = "^((?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)\\.)+(?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)$";

   static {
       pDomainNameOnly1 = Pattern.compile(DOMAIN_NAME_PATTERN_CHK_1);
       pDomainNameOnly2 = Pattern.compile(DOMAIN_NAME_PATTERN_CHK_2);
   }

   public static boolean isValidDomainName(String domainName) {
       return (pDomainNameOnly1.matcher(domainName).find() || pDomainNameOnly2.matcher(domainName).find() || domainName.equals(" "));
   }

}

и

//Main.java
public class Main{
   public static void main(String[] args){
       boolean valid = DomainUtils.isValidDomainName("a123456789a123456789a123456789a123456789a123456789a1234567891234.ARPA"); //check if domain name is valid or not
       System.out.println("Valid domain name : " + valid);
   }

}

Я просто хотел проверить, есть ли какой-нибудь эффективный способ (отличный от того, что я написал), чтобы проверить, является ли доменное имя действительным по стандарту rfc 1035? Также еслиМне нужно проверить, работает ли мой код для угловых случаев для стандарта rfc 1035, тогда где я могу проверить. Существуют ли какие-либо библиотеки, которые я могу использовать для этой проверки?

1 Ответ

1 голос
/ 04 июля 2019

Попробуйте это:

^[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$

, как показано в этом демо

Чтобы построить это выражение, мы сначала используем компонент метки (один символ в наборе a-zA-Z, за которым (необязательно) следует последовательность символов в наборе a-zA-Z0-9- и заканчивающаяся не - (дефис разрешено внутри, но не в начале или в конце метки), приводя к

[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?

это выражение повторяется по следующей схеме:

A(\.A)*

, что означает последовательность A, за которой следует любое количество (даже 0) последовательностей точки, за которой следует еще один экземпляр A.

Подставляя вышеупомянутые reges в позиции A, мы получаем последнее регулярное выражение. Якоря исключают любые другие окружающие строки в начале / конце строки.

Чтобы проверить, что метки имеют до 63 символов, вы можете сделать

[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?

но будьте осторожны, так как это регулярное выражение компилируется в очень большой табличный автомат (автомат со многими состояниями), так что вам лучше расслабиться, если у вас мало места.

...